真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

unixXSIIPC-信號量同步例程

原理不多講,可能查看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)限制

  • 信號量最大值 32767
  • 最多信號量集 128
  • 每個集中最多含有250信號量

難理解的是標(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)程

的每一個信號燈數(shù)組都維護(hù)一個 sem_undo 的數(shù)據(jù)結(jié)構(gòu)。如果請求的進(jìn)程沒有,就在需
要的時候為它創(chuàng)建一個。這個新的 sem_undo 數(shù)據(jù)結(jié)構(gòu)同時在進(jìn)程的 task_struct 數(shù)據(jù)
結(jié)構(gòu)和信號燈隊列的 semid_ds 數(shù)據(jù)結(jié)構(gòu)的隊列中排隊。對信號燈隊列中的信號燈執(zhí)行
操作的時候,和這個操作值相抵消的值加到這個進(jìn)程的 sem_undo 數(shù)據(jù)結(jié)構(gòu)的調(diào)整隊列
這個信號燈的條目上。所以,如果操作值為 2 ,那么這個就在這個信號燈的調(diào)整條目上
 
增加 -2 。 
 
 
   當(dāng)進(jìn)程被刪除,比如退出的時候, Linux 遍歷它的 sem_undo 數(shù)據(jù)結(jié)構(gòu)組,并
 
實(shí)施對于信號燈數(shù)組的調(diào)整。如果刪除信號燈,它的 sem_undo 數(shù)據(jù)結(jié)構(gòu)仍舊停留在進(jìn)
 
程的 task_struct 隊列中,但是相應(yīng)的信號燈數(shù)組標(biāo)識符標(biāo)記為無效。這種情況下,清除
信號燈的代碼只是簡單地廢棄這個 sem_undo 數(shù)據(jù)結(jié)構(gòu)。

http://3521632.blog.163.com/blog/static/110237933201032041353708/


以下例程

第一:先執(zhí)行init.c初始化,讓信號量集的第1個信號量值為1,當(dāng)然電腦索引是從0開始的;

第二:再執(zhí)行多個test.c



intit.c


  1. #include  
  2. #include  
  3. #include  
  4. #include  
  5. #include  
  6. #include  
  7. #include  
  8.  
  9. int open_semque(void); 
  10. void set_sem(int, int); 
  11. #if 1 

  12. union semun 
  13.       int val; 
  14.       struct semid_ds buf; 
  15.       unsigned short *array; 
  16. }; 
  17.  
  18. #endif 
  19.  
  20.  
  21. int main(int argc,char** argv) 
  22.       int ret; 
  23.        
  24.       int semque_id; 
  25.       semque_id = open_semque(); 
  26.         
  27.       set_sem(semque_id, 1); 
  28.       ret = semctl(semque_id, 0, GETVAL); 
  29.       printf("信號集中第一個信號量的值為:%d\n",ret); 
  30.        
  31.        
  32.       return 0; 
  33.  
  34.  
  35. int open_semque(void) 

  36. //創(chuàng)建一個鍵
  37.       key_t key = ftok("./",100); 
  38.        
  39.       if(key == -1) 
  40.       { 
  41.             perror("ftok\n"); 
  42.             exit(1); 
  43.       } 
  44. //創(chuàng)建信號量集,
  45. //IPC_CREAT存在則打開,不存在則新建,
  46. //0666是權(quán)限
  47. //設(shè)置這個信號量集中包含幾個信號量,設(shè)為1        
  48.       int semque_id = semget(key, 1,IPC_CREAT|0666); 
  49.       if(semque_id  == -1) 
  50.       { 
  51.             perror("msgget\n"); 
  52.             exit(1); 
  53.       } 
  54.        
  55.       return semque_id; 
  56.  
  57. void set_sem(int semque_id, int val) 
  58. //此聯(lián)合體需要自己去創(chuàng)建,在初始化信號量時需要這個聯(lián)合體;
  59.       union semun sem_union; 
  60.        
  61.       sem_union.val = val; 
  62.        
  63.      if(semctl(semque_id, 0, SETVAL, sem_union) == -1) 
  64.      { 
  65.             perror("semctl_set\n"); 
  66.             exit(1);      
  67.      } 



test.c


  1. #include  
  2. #include  
  3. #include  
  4. #include  
  5. #include  
  6. #include  
  7. #include  
  8.  
  9. void v_sem(int); 
  10. void p_sem(int); 
  11. int open_semque(void); 
  12. void set_sem(int, int); 
  13. #if 1 
  14. union semun 
  15.       int val; 
  16.       struct semid_ds buf; 
  17.       unsigned short *array; 
  18. }; 
  19.  
  20. #endif 
  21.  
  22.  
  23. int main(int argc,char** argv) 
  24.       int ret; 
  25.        
  26.       int semque_id; 
  27.       semque_id = open_semque(); 
  28.         
  29.       //set_sem(semque_id, 1); 
  30.       ret = semctl(semque_id, 0, GETVAL); 
  31.       printf("信號集中第一個信號量的值為:%d\n",ret); 
  32.        
  33.       fputs("執(zhí)行操作V\n",stdout); 
  34.        
  35.       v_sem(semque_id); 
  36.       ret = semctl(semque_id, 0, GETVAL); 
  37.       printf("信號集中第一個信號量的值為:%d\n",ret); 
  38.        
  39.       int second = 10; 
  40.       while(second) 
  41.       { 
  42.             sleep(1); 
  43.             printf("%ds\n",second); 
  44.             ret = semctl(semque_id, 0, GETVAL); 
  45.             printf("信號集中第一個信號量的值為:%d\n",ret); 
  46.             second--; 
  47.       } 
  48.        
  49.  
  50.        
  51.       fputs("執(zhí)行操作P\n",stdout); 
  52.       p_sem(semque_id); 
  53.       ret = semctl(semque_id, 0, GETVAL); 
  54.       printf("信號集中第一個信號量的值為:%d\n",ret); 
  55.  
  56.       //semctl(semque_id, 0, IPC_RMID); 
  57.  
  58.       return 0; 
  59.  
  60.  
  61. int open_semque(void) 
  62.       key_t key = ftok("./",100); 
  63.        
  64.       if(key == -1) 
  65.       { 
  66.             perror("ftok\n"); 
  67.             exit(1); 
  68.       } 
  69.        
  70.       int semque_id = semget(key, 1,IPC_CREAT|0666); 
  71.       if(semque_id  == -1) 
  72.       { 
  73.             perror("msgget\n"); 
  74.             exit(1); 
  75.       } 
  76.        
  77.       return semque_id; 
  78.  
  79. void set_sem(int semque_id, int val) 
  80.       union semun sem_union; 
  81.        
  82.       sem_union.val = val; 
  83.        
  84.      if(semctl(semque_id, 0, SETVAL, sem_union) == -1) 
  85.      { 
  86.             perror("semctl_set\n"); 
  87.             exit(1);      
  88.      } 
  89.  
  90. void p_sem(int semque_id) 
  91.       struct sembuf arry[1]; 
  92.       arry[0].sem_num = 0; 
  93.       arry[0].sem_op = 1; 
  94.       //arry[0].sem_flg = SEM_UNDO; 
  95.        
  96.       int ret; 
  97. //需要通過結(jié)構(gòu)體struct sembuf進(jìn)行賦值       
  98.       if(ret = semop(semque_id, arry, 1)) 
  99.       { 
  100.             perror("semop\n"); 
  101.             exit(1);        
  102.       } 
  103.  
  104.  
  105. void v_sem(int semque_id) 
  106.       struct sembuf arry[1]; 
  107.       arry[0].sem_num = 0; 
  108.       arry[0].sem_op = -1; 
  109.       //arry[0].sem_flg = IPC_NOWAIT; 
  110.       arry[0].sem_flg = SEM_UNDO; 
  111.        
  112.       int ret; 
  113.        
  114.       if(ret = semop(semque_id, arry, 1)) 
  115.       { 
  116.             perror("semop\n"); 
  117.             exit(1);        
  118.       } 

 


分享文章:unixXSIIPC-信號量同步例程
當(dāng)前URL:http://weahome.cn/article/gscoec.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部