溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

進程間通信之信號量

發(fā)布時間:2020-05-27 19:16:27 來源:網(wǎng)絡(luò) 閱讀:501 作者:小止1995 欄目:編程語言

信號量:相當(dāng)于一個計數(shù)器,計錄當(dāng)前環(huán)境某種資源個數(shù)。沒有對信號進行傳輸,保證對信號量操作是原子的。主要為了保護臨界資源。生命周期隨內(nèi)核。

臨界區(qū):訪問共享資源的代碼區(qū)

臨界資源:進程間所共享的資源

互斥:同一時刻,只允許一個進程對這份資源訪問,這個進程對資源具有獨占性,排他性。

同步:互斥情況下,進程對臨界資源訪問具有順序。

信號量有兩個基本操作:P,V

p:減一,向信號量申請資源,申請到后若p=0,則將進程掛起,否則信號量減一。

v:加一,使用資源完畢,歸還給系統(tǒng),若有進程掛起,則喚醒等待進程或線程,否則將信號量加一。

使用到的主要函數(shù)原型:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h> 

int semget(key_t key, int nsems, int semflg);

int semctl(int semid, int semnum, int cmd, ...);

int semop(int semid, struct sembuf *sops, unsigned nsops);

union semun {

               int              val;    /* Value for SETVAL */

               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */

               unsigned short  *array;  /* Array for GETALL, SETALL */

               struct seminfo  *__buf;  /* Buffer for IPC_INFO

                                           (Linux-specific) */

           };

 struct sembuf{

          unsigned short sem_num;  /* semaphore number */

           short          sem_op;   /* semaphore operation */

           short          sem_flg;  /* operation flags */

          }中sem_flg表示以什么形式控制信號量,0表示默認(rèn),SEM_NODO表示取消

注意:信號量的創(chuàng)建是以信號量集的形式創(chuàng)建

    當(dāng)semctl(semid,semnum,cmd);要刪除時cmd被設(shè)置為IPC_RMID,semnum被忽視。當(dāng)cmd為SETVAL時,對第semnum個信號量初始化。

   信號量集中信號量從0開始

grep  -ER 'semum' /usr/include/  查詢semum

//comm.h
  1 #pragma once
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<unistd.h>
  5 #include<sys/types.h>
  6 #include<sys/ipc.h>
  7 #include<sys/sem.h>
  8 #define _PATH_ "."
  9 #define _PROJ_ID_ 0x8888
 10 union semun
 11 {
 12     int val;
 13     struct semid_ds* buf;
 14     unsigned short  *array;
 15     struct seminfo  *__buf;
 16 };
 17 //struct sembuf
 18 //{
 19 //  unsigned short sem_num;
 20 //  short sem_op; 
 21 //  short sem_flg;
 22 // };
 23 static int _sem_set(int snum,int flags);
 24 static int sem_op(int sem_id,int nsops,int flags);
 25 int create_sem(int snum);
 26 int get_sem(int snum);
 27 int init_sem(int sem_id,int snum,int unit_val);
 28 int sem_p_element(int sem_id,int nsops);
 29 int sem_v_element(int sem_id,int nsops);
 30 int destory_sem_element(int sem_id);
 //comm.c
  1 #include"comm.h"
  2 static int _sem_set(int snum,int flags)
  3 {
  4     key_t _key=ftok(_PATH_,_PROJ_ID_);
  5     if(_key<0)
  6     {
  7         perror("ftok");
  8         return -1;
  9     }
 10     int sem_id=-1;
 11     sem_id=semget(_key,snum,flags);
 12     if(sem_id<0)
 13     {
 14        
 15         perror("semget");
 16         return -1;
 17     }
 18     return sem_id;
 19 }
 20 
 21 int create_sem(int snum)
 22 {
 23     int flags=IPC_CREAT|IPC_EXCL|0666;
 24     int ret= _sem_set(snum,flags);
 25     return ret;
 26 }
 27 int get_sem(int snum)
 28 {
 29     return _sem_set(snum,IPC_CREAT);
 30 }
 31 int init_sem(int sem_id,int snum,int unit_val)
 32 {
 33     union semun _un;
 34     _un.val=unit_val;
 35     if(semctl(sem_id,snum,SETVAL,_un)<0)
 36     {
 37             perror("semctl\n");
 38         return -1;
 39     }
 40     return 0;
 41 }
 42 static int sem_op(int sem_id,int seqnum,int op)
 43 {
 44     struct sembuf _sm;
 45     _sm.sem_num=seqnum;
 46     _sm.sem_op=op;
 47     _sm.sem_flg=0;
 48     if(semop(sem_id,&_sm,1)<0)
 49     {
 50         perror("semop");
 51         return -1;
 52     }
 53     return 0;
 54 }
 55 int sem_p_element(int sem_id,int seqnum)
 56 {
 57     return sem_op(sem_id,seqnum,-1);
 58 }
 59 int sem_v_element(int sem_id,int seqnum)
 60 {
 61     return sem_op(sem_id,seqnum,1);
 62 }
 63 int destory_sem_element(int sem_id)
 64 {
 65     if(semctl(sem_id,IPC_RMID,0,NULL)<0)
 66     {
 67         perror("semctl\n");
 68         return -1;
 69     }
 70     return 0;
 71 }
 //test.c
  1 #include"comm.h"
  2 int main()
  3 {
  4     int sem_id=create_sem(1);
  5     if(sem_id<0)
  6     {
  7         printf("error\n");
  8         return -1;
  9     }
 10     init_sem(sem_id,1,1);
 11     pid_t pid=fork();
 12     if(pid<0)
 13     {
 14         perror("pid");
 15         return -1;
 16     }
 17     else if(pid==0)
 18     {
 19         int sem_pid=get_sem(1);
 20         while(1)
 21         {
 22             sem_p_element(sem_pid,0);
 23             printf("A");                                 
 24             sleep(1);
 25             fflush(stdout);
 26             printf("A");
 27             sleep(8);
 28             fflush(stdout);
 29             sem_v_element(sem_pid,0);
 30         }
 31     }
 32     else
 33     {
 34         while(1)
 35         {
 36             sem_p_element(sem_id,0);
 37             sleep(3);
 38             printf("B");
 39             sleep(2);
 40             fflush(stdout);
 41             printf("B");
 42             sleep(5);
 43             fflush(stdout);
 44             sem_v_element(sem_id,0);
 45         }        
 46         waitpid(pid,NULL,0);
 47         destory_sem_element(sem_id);
 48  
 49     }
 50     return 0;
 51 }
 //Makefile
  1 .PHONY:all
  2 all:test
  3 test:test.c comm.c
  4     gcc -o $@ $^
  5 .PHONY:clean
  6 clean:
  7     rm -f test

未使用信號量之前:進程間通信之信號量

使用后:

進程間通信之信號量


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI