原理不多講,可能查看unix 高級環(huán)境編程,只提一些注意點(diǎn)
成都創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的玉山網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
信號量系統(tǒng)限制
難理解的是標(biāo)志位SEM_UNDO
以下是個人愚見:
首先是了解一下"信號量調(diào)整值",每一個信號量都會對應(yīng)有一個調(diào)整值,并且對信號量進(jìn)行操作的時候進(jìn)行維護(hù)。如果設(shè)置了SEM_UNDO則立即更新,如果沒有何時更新,我也不知道,可能是系統(tǒng)調(diào)度吧;
在進(jìn)行退出,無論是正常還是異常,內(nèi)核都會遍歷一次進(jìn)程的調(diào)整值,進(jìn)行處理,具體怎樣處理有待研究;
個人經(jīng)驗:如果在V 和 P 操作上, 如果需要阻塞的,最好標(biāo)志位上賦SEM_UNDO,如果不阻塞那就不需要,這樣會少點(diǎn)意想不到的錯誤
網(wǎng)上解釋:
每一個獨(dú)立的信號燈操作可能都需要維護(hù)一個調(diào)整動作。 Linux 至少為每一個進(jìn)程
http://3521632.blog.163.com/blog/static/110237933201032041353708/
以下例程
第一:先執(zhí)行init.c初始化,讓信號量集的第1個信號量值為1,當(dāng)然電腦索引是從0開始的;
第二:再執(zhí)行多個test.c
intit.c
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- int open_semque(void);
- void set_sem(int, int);
- #if 1
- union semun
- {
- int val;
- struct semid_ds buf;
- unsigned short *array;
- };
- #endif
- int main(int argc,char** argv)
- {
- int ret;
- int semque_id;
- semque_id = open_semque();
- set_sem(semque_id, 1);
- ret = semctl(semque_id, 0, GETVAL);
- printf("信號集中第一個信號量的值為:%d\n",ret);
- return 0;
- }
- int open_semque(void)
- {
//創(chuàng)建一個鍵- key_t key = ftok("./",100);
- if(key == -1)
- {
- perror("ftok\n");
- exit(1);
- }
- //創(chuàng)建信號量集,
- //IPC_CREAT存在則打開,不存在則新建,
- //0666是權(quán)限
- //設(shè)置這個信號量集中包含幾個信號量,設(shè)為1
- int semque_id = semget(key, 1,IPC_CREAT|0666);
- if(semque_id == -1)
- {
- perror("msgget\n");
- exit(1);
- }
- return semque_id;
- }
- void set_sem(int semque_id, int val)
- {
- //此聯(lián)合體需要自己去創(chuàng)建,在初始化信號量時需要這個聯(lián)合體;
- union semun sem_union;
- sem_union.val = val;
- if(semctl(semque_id, 0, SETVAL, sem_union) == -1)
- {
- perror("semctl_set\n");
- exit(1);
- }
- }
test.c
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- void v_sem(int);
- void p_sem(int);
- int open_semque(void);
- void set_sem(int, int);
- #if 1
- union semun
- {
- int val;
- struct semid_ds buf;
- unsigned short *array;
- };
- #endif
- int main(int argc,char** argv)
- {
- int ret;
- int semque_id;
- semque_id = open_semque();
- //set_sem(semque_id, 1);
- ret = semctl(semque_id, 0, GETVAL);
- printf("信號集中第一個信號量的值為:%d\n",ret);
- fputs("執(zhí)行操作V\n",stdout);
- v_sem(semque_id);
- ret = semctl(semque_id, 0, GETVAL);
- printf("信號集中第一個信號量的值為:%d\n",ret);
- int second = 10;
- while(second)
- {
- sleep(1);
- printf("%ds\n",second);
- ret = semctl(semque_id, 0, GETVAL);
- printf("信號集中第一個信號量的值為:%d\n",ret);
- second--;
- }
- fputs("執(zhí)行操作P\n",stdout);
- p_sem(semque_id);
- ret = semctl(semque_id, 0, GETVAL);
- printf("信號集中第一個信號量的值為:%d\n",ret);
- //semctl(semque_id, 0, IPC_RMID);
- return 0;
- }
- int open_semque(void)
- {
- key_t key = ftok("./",100);
- if(key == -1)
- {
- perror("ftok\n");
- exit(1);
- }
- int semque_id = semget(key, 1,IPC_CREAT|0666);
- if(semque_id == -1)
- {
- perror("msgget\n");
- exit(1);
- }
- return semque_id;
- }
- void set_sem(int semque_id, int val)
- {
- union semun sem_union;
- sem_union.val = val;
- if(semctl(semque_id, 0, SETVAL, sem_union) == -1)
- {
- perror("semctl_set\n");
- exit(1);
- }
- }
- void p_sem(int semque_id)
- {
- struct sembuf arry[1];
- arry[0].sem_num = 0;
- arry[0].sem_op = 1;
- //arry[0].sem_flg = SEM_UNDO;
- int ret;
- //需要通過結(jié)構(gòu)體struct sembuf進(jìn)行賦值
- if(ret = semop(semque_id, arry, 1))
- {
- perror("semop\n");
- exit(1);
- }
- }
- void v_sem(int semque_id)
- {
- struct sembuf arry[1];
- arry[0].sem_num = 0;
- arry[0].sem_op = -1;
- //arry[0].sem_flg = IPC_NOWAIT;
- arry[0].sem_flg = SEM_UNDO;
- int ret;
- if(ret = semop(semque_id, arry, 1))
- {
- perror("semop\n");
- exit(1);
- }
- }