創(chuàng)建一個(gè)信號(hào)量
//創(chuàng)建之后一直存在,除非主動(dòng)刪除
int sem_id;
//semget第二個(gè)參數(shù)為信號(hào)量集(數(shù)組)中信號(hào)量的個(gè)數(shù)
sem_id = semget(1000,1,IPC_CREAT|0600);
ERROR_CHECK(sem_id,-1,"semget");
將信號(hào)量初始化|設(shè)置信號(hào)量的值
//semctl函數(shù)
//第二個(gè)參數(shù)為信號(hào)量在信號(hào)量集(數(shù)組)中的下標(biāo)
//初始化時(shí),第三個(gè)參數(shù)為 SETVAL
//第四個(gè)參數(shù)為初始化的值
int ret = semctl(sem_id,0,SETVAL,1);
//成功返回0
ERROR_CHECK(ret,-1,"semctl");
獲取信號(hào)量的值
ret = semctl(sem_id,0,GETVAL);
ERROR_CHECK(ret,-1,"semctl");
實(shí)現(xiàn)PV操作
//P定義一個(gè)結(jié)構(gòu)體
//V定義一個(gè)結(jié)構(gòu)體
struct sembuf sopp,sopv;
//P操作
sopp.sem_num = 0;
sopp.sem_op = -1;
sopp.sem_flag = SEM_UNDO;
//V操作
sopv.sem_num = 0;
sopv.sem_op = 1;
sopv.sem_flag = SEM_UNDO;
if(!fork())
{
for(int i=0;i<100000000;i++)
{
//加鎖
semop(sem_id,&sopp,1);
p_start[0] = p_start[0]+1;
//解鎖
semop(sem_id,&sopv,1);
}
}
參數(shù)cmd為執(zhí)行的操作
- IPC_RMID 立即刪除信號(hào)量,喚醒所有被阻塞的進(jìn)程
- GETVAL 返回信號(hào)量的值,從0開(kāi)始,第一個(gè)信號(hào)量編號(hào)為0
- SETVAL 設(shè)定信號(hào)量的值,從0開(kāi)始,第一個(gè)信號(hào)量編號(hào)為0
刪除信號(hào)量集合
//刪除信號(hào)量集合
ret = semctl(sem_id,0,IPC_RMID);
ERROR_CHECK(ret,-1,"semctl");
批量設(shè)置多個(gè)信號(hào)量的值
unsigned short arrays[2]={0,10};
int ret = semctl(sem_id,0,SETALL,arrays);
生產(chǎn)者消費(fèi)者
#include <func.h>
int main(int argc,char*argv[])
{
int sem_id;
//兩個(gè)信號(hào)量
sem_id = semget(1000,2,IPC_CREAT|0600);
ERROR_CHECK(sem_id,-1,"semctl");
//生產(chǎn)者消費(fèi)者 計(jì)數(shù)信號(hào)量
//0號(hào)信號(hào)量代表產(chǎn)品數(shù)目
//1號(hào)信號(hào)量代表倉(cāng)庫(kù)數(shù)目
unsigned short arrays[2]={0,10};
int ret;
//對(duì)兩個(gè)信號(hào)量同時(shí)進(jìn)行初始化
ret = semctl(sem_id,0,SETALL,arrays);
ERROR_CHECK(ret,-1,"semctl");
//將arrays都設(shè)置為0
//memset(arrays,0,sizeof(arrays));
//子進(jìn)程是出庫(kù)進(jìn)程,消費(fèi)者
//父進(jìn)程是入庫(kù)進(jìn)程,生產(chǎn)者
if(!fork()){
//出庫(kù),產(chǎn)品-,倉(cāng)庫(kù)空間+,故0號(hào)信號(hào)量p操作,1號(hào)信號(hào)量v操作
struct sembuf sopp0,sopv1;
sopp0.sem_num=0;
sopp0.sem_op=-1;
sopp0.sem_flg=SEM_UNDO;
sopv1.sem_num=1;
sopv1.sem_op=1;
sopv1.sem_flg=SEM_UNDO;
while(1){
//子進(jìn)程出庫(kù)
printf("I am Customer,product num = %d space num = %d \n",semctl(sem_id,0,GETVAL),semctl(sem_id,1,GETVAL));
//對(duì)產(chǎn)品-1 P操作
semop(sem_id,&sopp0,1);
printf("start out...\n");
//對(duì)倉(cāng)庫(kù)個(gè)數(shù)+1
semop(sem_id,&sopv1,1);
printf("I am Customer,product num = %d space num = %d \n",semctl(sem_id,0,GETVAL),semctl(sem_id,1,GETVAL));
sleep(2);
}
}else{
//入庫(kù)
//產(chǎn)品+,倉(cāng)庫(kù)空間-, 0號(hào)信號(hào)量+1,1號(hào)信號(hào)量-1
struct sembuf sopp1,sopv0;
sopv0.sem_num=0;//在信號(hào)量集合中的編號(hào)
sopv0.sem_op=1;//V操作 +1
sopv0.sem_flg=SEM_UNDO;
sopp1.sem_num=1;
sopp1.sem_op=-1;
sopp1.sem_flg=SEM_UNDO;
while(1)
{
printf("I am Productor,product num = %d space num = %d\n",semctl(sem_id,0,GETVAL),semctl(sem_id,1,GETVAL));
//對(duì)倉(cāng)庫(kù)數(shù)-1,先要有位置了才能放入
semop(sem_id,&sopp1,1);
printf("start in...\n");
//產(chǎn)品數(shù)+1
semop(sem_id,&sopv0,1);
printf("I am Productor,product num = %d space num = %d\n",semctl(sem_id,0,GETVAL),semctl(sem_id,1,GETVAL));
sleep(1);
}
}
return 0;
}
SEM_UNDO
設(shè)置為SEM_UNDO,當(dāng)殺掉一個(gè)進(jìn)程的時(shí)候,這個(gè)進(jìn)程對(duì)該某信號(hào)的操作會(huì)較初始值全部反向操作回去.(若P操作減了三十次,則較初始值加回三十)
若要減三十多次,不能減為負(fù)值,那就為0
PV的非計(jì)數(shù)信號(hào)量,需要用SEM_UNDO.