//semctl函數的作用是用來直接控制信號量信息intsemctl(intsem_" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Linux學習筆記26——信號量

系統 2304 0

一 信號量的基本概念

  信號量:它是一個特殊變量,只允許對它進行等待和發送信號這兩種操作。
  假設有一個信號量變量sv
  P(sv):用于等待,如果sv的值大于零,就給它減去1,如果它的值等于零,就掛起該進程的執行。
  V(sv):用于發送信號,如果有其他進程因等待sv而被掛起,就讓它恢復運行,如果沒有進程因等待sv而被掛起,就給它加1

二 信號量的相關函數

      
        #include <sys/sem.h>
      
      
//semctl函數的作用是用來直接控制信號量信息 int semctl( int sem_id,             //由semget返回的信號量標識符
int sem_num,            //是信號量編號,當需要用到成組的信號量時,就要用到這個參數,它一般取值為0,表示這是第一個也是唯一的信號量
int command,            //是將要采取的動作
       ...                 //它將會是一個union semun結構
      );
//semget函數的作用是創建一個新信號量或取得一個已有信號量的鍵。
int semget(key_t key, //key是整數值,不相關的進程可以通過它訪問同一個信號量
       int
num_sems,           //指定需要的信號量數目,幾乎總是取值為1

int sem_flags           //是一組標志,與open函數的標志非常相似
      );                  //在成功時返回一個正數(非零)值,它就是其他信號量函數將用到的信號量標識符,如果失敗,則返回-1
//semop函數用于改變信號量的值
int semop( int sem_id,            //由semget返回的信號量標識符
struct sembuf *sem_ops,    //指向一個 sembuf 結構數組的指針
      size_t num_sem_ops //信號操作結構的數量,恒大于或等于1
     );

semun包含于semun.h頭文件中

      
        
          union semun{ 
        
        
          int
        
        
           val;          
          
            //SETVAL所設置的信號量集中的一個信號量的值 
          
        
        
          struct
        
         semid_ds *
        
          buf; 
          
             //IPC_STAT,IPC_SET存儲的數據
          
           unsigned 
        
        
          short
        
         *
        
          array; 
          
             //GETALL, SETALL返回值的數組
          
           }
        
      
    

  semop函數中的sembuf結構體

      
        
          struct
        
        
           sembuf{ 
        
        
          short
        
        
           sem_num;  
          
            //信號量編號,除非需要使用一組信號量,否則它的取值一般為0 
          
        
        
          short
        
         sem_op;   
        
          //是信號量在一次操作中需要改變的數值,通常只會用到兩個值,一個是-1,也就是P操作,它等待信號量變為己用;一個是+1,也就是V操作,它發送信號表示信號量現在已可用 
        
        
          short
        
        
           sem_flg;  
          
            //通常設置為SEM_UNDO,它將使得操作系統跟蹤當前進程對這個信號量的修改情況
          
           }
        
      
    

  semctl中第三個參數command取值如下:

    ·IPC_STAT:讀取一個信號量集的數據結構semid_ds,并將其存儲在semun中的buf參數中。
    ·IPC_SET:設置信號量集的數據結構semid_ds中的元素ipc_perm,其值取自semun中的buf參數。
    ·IPC_RMID:將信號量集從內存中刪除。
    ·GETALL:用于讀取信號量集中的所有信號量的值。
    ·GETNCNT:返回正在等待資源的進程數目。
    ·GETPID:返回最后一個執行semop操作的進程的PID。
    ·GETVAL:返回信號量集中的一個單個的信號量的值。
    ·GETZCNT:返回這在等待完全空閑的資源的進程數目。
    ·SETALL:設置信號量集中的所有的信號量的值。
    ·SETVAL:設置信號量集中的一個單獨的信號量的值。


三 例子

      
        #include <unistd.h>
        
           #include 
        
        <stdlib.h>
        
           #include 
        
        <stdio.h>
        
           #include 
        
        <sys/sem.h>
        
           #include 
        
        
          "
        
        
          semun.h
        
        
          "
        
        
          static
        
        
          int
        
         set_semvalue(
        
          void
        
        
          ); 
        
        
          static
        
        
          void
        
         del_semvalue(
        
          void
        
        
          ); 
        
        
          static
        
        
          int
        
         semaphore_p(
        
          void
        
        
          ); 
        
        
          static
        
        
          int
        
         semaphore_v(
        
          void
        
        
          ); 
        
        
          static
        
        
          int
        
        
           sem_id; 
        
        
          int
        
         main(
        
          int
        
         argc,
        
          char
        
         *
        
          argv[]){ 
        
        
          int
        
        
           i; 
        
        
          int
        
        
           pause_time; 
        
        
          char
        
         op_char=
        
          '
        
        
          0
        
        
          '
        
        
          ; srand((unsigned 
        
        
          int
        
        
          )getpid()); sem_id
        
        =semget((key_t)
        
          1234
        
        ,
        
          1
        
        ,
        
          0666
        
        |
        
          IPC_CREAT); 
        
        
          if
        
        (argc>
        
          1
        
        
          ){ 
        
        
          if
        
        (!
        
          set_semvalue()){ fprintf(stderr,
        
        
          "
        
        
          Failed to initialize semaphore\n
        
        
          "
        
        
          ); exit(EXIT_FAILURE); } op_char
        
        =
        
          '
        
        
          X
        
        
          '
        
        
          ; sleep(
        
        
          2
        
        
          ); } 
        
        
          //
        
        
          進入和離開臨界區域10次,在每次循環的開始,首先調用semaphore函數,它在程序進入臨界區域時設置信號量以等待進入
        
        
          for
        
        (i=
        
          0
        
        ;i<
        
          10
        
        ;i++
        
          ){ 
        
        
          if
        
        (!
        
          semaphore_p()){ exit(EXIT_FAILURE); } printf(
        
        
          "
        
        
          %c
        
        
          "
        
        
          ,op_char); fflush(stdout); pause_time
        
        =rand()%
        
          3
        
        
          ; sleep(pause_time); printf(
        
        
          "
        
        
          %c
        
        
          "
        
        
          ,op_char); fflush(stdout); 
        
        
          //
        
        
          臨界區域之后,調用semaphore_v來將信號量設置為可用,然后等待一段隨機時間,再進入下一次循環。在整個循環語句執行完畢后,調用del_semvalue函數來清理代碼
        
        
          if
        
        (!
        
          semaphore_v()){ exit(EXIT_FAILURE); } pause_time
        
        =rand()%
        
          2
        
        
          ; sleep(pause_time); } printf(
        
        
          "
        
        
          \n%d - finished\n
        
        
          "
        
        
          ,getpid()); 
        
        
          if
        
        (argc>
        
          1
        
        
          ){ sleep(
        
        
          5
        
        
          ); del_semvalue(); } exit(EXIT_SUCCESS); } 
        
        
          //
        
        
          函數set_semvalue通過將semct1調用的command參數設置為SETVAL來初始化信號量
        
        
          static
        
        
          int
        
         set_semvalue(
        
          void
        
        
          ){ union semun sem_union; sem_union.val
        
        =
        
          1
        
        
          ; 
        
        
          if
        
        (semctl(sem_id,
        
          0
        
        ,SETVAL,sem_union)==-
        
          1
        
        
          ){ 
        
        
          return
        
        
          0
        
        
          ; } 
        
        
          return
        
        
          1
        
        
          ; } 
        
        
          static
        
        
          void
        
         del_semvalue(
        
          void
        
        
          ){ union semun sem_union; 
        
        
          if
        
        (semctl(sem_id,
        
          0
        
        ,IPC_RMID,sem_union)==-
        
          1
        
        
          ){ fprintf(stderr,
        
        
          "
        
        
          Failed to delete semaphore
        
        
          "
        
        
          ); } } 
        
        
          //
        
        
          semaphore_p對信號量做減1操作(等待)
        
        
          static
        
        
          int
        
         semaphore_p(
        
          void
        
        
          ){ 
        
        
          struct
        
        
           sembuf sem_b; sem_b.sem_num
        
        =
        
          0
        
        
          ; sem_b.sem_op
        
        =-
        
          1
        
        
          ; sem_b.sem_flg
        
        =
        
          SEM_UNDO; 
        
        
          if
        
        (semop(sem_id,&sem_b,
        
          1
        
        )==-
        
          1
        
        
          ){ fprintf(stderr,
        
        
          "
        
        
          semaphore_p failed\n
        
        
          "
        
        
          ); 
        
        
          return
        
        
          0
        
        
          ; } 
        
        
          return
        
        
          1
        
        
          ; } 
        
        
          //
        
        
          semaphore_v將sembuf結構中的sem_op設置為1,釋放操作
        
        
          static
        
        
          int
        
         semaphore_v(
        
          void
        
        
          ){ 
        
        
          struct
        
        
           sembuf sem_b; sem_b.sem_num
        
        =
        
          0
        
        
          ; sem_b.sem_op
        
        =
        
          1
        
        
          ; sem_b.sem_flg
        
        =
        
          SEM_UNDO; 
        
        
          if
        
        (semop(sem_id,&sem_b,
        
          1
        
        )==-
        
          1
        
        
          ){ fprintf(stderr,
        
        
          "
        
        
          semaphore_v failed\n
        
        
          "
        
        
          ); 
        
        
          return
        
        
          0
        
        
          ; } 
        
        
          return
        
        
          1
        
        
          ; }
        
      
    

?

Linux學習筆記26——信號量


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!??!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 女人大毛片一级毛片一 | 天堂va亚洲va欧美va国产 | 99久久亚洲 | 99j久久精品久久久久久 | 天天干天天干天天插 | 免费a级在线观看完整片 | 欧美一区二区三区视频在线 | 久久日本经典片免费看 | 九九精品热 | 天天艹日日干 | 天天综合天天综合 | 日韩一区三区 | 国产高清一区二区三区视频 | 国产第一页久久亚洲欧美国产 | 欧美成人免费全网站大片 | 免费91视频 | 中文国产成人精品久久久 | 九九视频高清视频免费观看 | 亚洲天天做日日做天天欢毛片 | 国产精品久久香蕉免费播放 | 一级特级aa欧美毛片 | 老司机亚洲精品影院在线 | 日日日日人人人夜夜夜2017 | 99热精品免费 | 丁香六月色婷婷 | 在线播放91 | 色就操 | 久久久久久亚洲精品影院 | 九九福利视频 | 亚洲天天在线日亚洲洲精 | 激情婷婷综合 | 亚洲精品伊人 | 天天夜天干天天爽 | 日本一级片在线观看 | 日韩国产欧美一区二区三区在线 | 久久婷婷午色综合夜啪 | 99热成人精品国产免国语的 | 亚洲欧美综合国产精品一区 | 欧美一级一极性活片免费观看 | 日韩毛片最新看 | 国产社区 |