当我们使用共享内存进行进程间的通信时,通常要对进程进行同步或者互斥的操作。
这里我们采用信号量的pv操作来完成进程间的互斥。
具体代码如下:
头文件:
sys/sem.h
errno.h
声明共用体类型:
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *buf;
};
信号量的初始化:
int init_sem(int semid, int num, int val)
{
union semun myun;
myun.val = val;
if(semctl(semid, num, SETVAL, myun) < 0)
{
perror("semctl");
exit(1);
}
return 0;
}
这里semid可用ftok函数获取,num代表我们要操作(初始化)该信号集合中的第几个信号,val代表要设置该信号的值。
在对一处共享资源的保护时,我们通常将num和val的设为0,1即:init_sem(semid,0,1);
P操作:
即将第num个信号的值减一的操作。
int sem_p(int semid, int num)
{
printf("sem_p start\n");
struct sembuf mybuf;
mybuf.sem_num = num;
mybuf.sem_op = -1;
mybuf.sem_flg = SEM_UNDO;
if(semop(semid, &mybuf, 1) < 0)
{
perror("semop");
exit(1);
}
printf("sem_p over\n");
return 0;
}
V操作:
即将第num个信号的值加一的操作。
int sem_v(int semid, int num)
{
struct sembuf mybuf;
mybuf.sem_num = num;
mybuf.sem_op = 1;
mybuf.sem_flg = SEM_UNDO;
if(semop(semid, &mybuf, 1) < 0)
{
perror("semop");
exit(1);
}
return 0;
}
定义好函数后,首先执行初始化函数:
init_sem(semid,0,1);
再在需要保护的临界资源上下分别加上p,v函数:
sem_p(semid, 0);
对临界资源的操作;
sem_v(semid, 0);
即可完成对临界资源的互斥操作。
注:初始化函数只在优先执行的进程中执行一次即可。