semget
http://man7.org/linux/man-pages/man2/semget.2.html
semctl
http://man7.org/linux/man-pages/man2/semctl.2.html
semop
http://man7.org/linux/man-pages/man2/semop.2.html
ftok
http://man7.org/linux/man-pages/man3/ftok.3.html
=============================================================================
程序示例:
struct semid_ds my_semds;
struct sembuf my_sembuf[1];
union semun my_semarg;
const char *pathname = "xxx";
key_t key = ftok(pathname, 1);
/* Create the semaphore */
semid = semget(key, 1, IPC_CREAT|IPC_EXCL|0666);
if (semid >= 0)
{
/* The semaphore was created first time. Initialize with value 1 */
my_semarg.val = 1;
rc = semctl(semid, 0, SETVAL, my_semarg);
if (rc == -1)
{
fprintf(stderr, "semctl failed, errno=%d\n", errno);
exit(1);
}
}
else
{
if (errno != EEXIST)
{
fprintf(stderr, "semget failed, errno=%d\n", errno);
exit(1);
}
/* The semaphore already exists. get its id. */
semid = semget(key, 1, 0);
/* otime 0 indicates there may be another process creating the sempahore
** at the same time.
*/
my_semarg.buf = &my_semds;
rc = semctl(semid, 0, IPC_STAT, my_semarg);
if (rc == -1)
{
fprintf(stderr, "semctl(IPC_STAT) failed, errno=%d\n", errno);
exit(1);
}
if (my_semds.sem_otime == 0)
{
/* Another process is running
*/
fprintf(stderr, "race condition detected.\n");
exit(1);
}
}
/* The IPC_NOWAIT flag is set for none blocking
** The SEM_UNDO is used for releasing semaphore when process exit
*/
my_sembuf[0].sem_num = 0; /* semaphore number, 0 is the first one */
my_sembuf[0].sem_op = -1; /* semaphore operation, -1 is subtract 1 from current value*/
my_sembuf[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
rc = semop(semid, my_sembuf, 1);
if (rc == -1)
{
if (errno == EAGAIN)
{
fprintf(stderr, "Semaphore is hold by another process.\n");
exit(2);
}
else
{
fprintf(stderr, "semop failed, errno=%d\n");
exit(1);
}
}
//Lock the semaphore successfully, continue other works
参考文献:
https://docs.oracle.com/cd/E19120-01/open.solaris/817-4415/svipc-65382/index.html