當我們使用共享內存進行進程間的通信時,通常要對進程進行同步或者互斥的操作。
這里我們采用信號量的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);
即可完成對臨界資源的互斥操作。
注:初始化函數只在優先執行的進程中執行一次即可。