注:本文章代码示例以及知识点来自《Linux高性能服务器编程》一书,对应章节13.5——信号量。
一、父、子进程间使用一个IPC_PRIVATE信号量来同步
Linux信号量的API有两组,一组是本文章中所使用的System V IPC信号量,其定义在sys/sem.h头文件中,主要包含3个系统调用:semget、semop、semctl,它们都被设计为操作一组信号量,即信号量集,而不是单个信号。;
另一组是与线程相关的POSIX信号量,其定义在头文件semaphore.h头文件中,具体参考章节14.4——POSIX信号量。
可以结合对比线程同步中的互斥锁来进行学习。
#include <sys/sem.h>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/wait.h>
union semun
{
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *_buf;
};
void pv(int sem_id, int op)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = op;
sem_b.sem_flg = SEM_UNDO;
semop(sem_id, &sem_b, 1);
}
int main(int argc, char *argv[])
{
int sem_id = semget(IPC_PRIVATE, 1, 0666);
union semun sem_un;
sem_un.val = 1;
semctl(sem_id, 0, SETVAL, sem_un);
pid_t id = fork();
if (id < 0)
{
return 1;
}
else if (id == 0)
{
printf("child try to get binary sem\n");
pv(sem_id, -1);
printf("child get the sem and would release it after 5 seconds\n");
sleep(5);
pv(sem_id, 1);
exit(0);
}
else
{
printf("parent try to get binary sem\n");
pv(sem_id, -1);
printf("parent get the sem and would release it after 5 seconds\n");
sleep(5);
pv(sem_id, 1);
}
waitpid(id, NULL, 0);
semctl(sem_id, 0, IPC_RMID, sem_un);
return 0;
}
二、运行结果