首頁 > 後端開發 > php教程 > Linux--進程間通訊-信號量

Linux--進程間通訊-信號量

黄舟
發布: 2023-03-04 22:42:01
原創
1252 人瀏覽過

一、什麼是信號量
就是一種用來描述某種資源數量個數的計數器,透過控制其他通訊資源來實現進程通訊。它在過程中負責資料的互斥、同步等。互斥,就是在同一時間段內,A、B兩個行程只有一個行程在運作。同步。就是A 進程完成之後,B進程接著完成,有一定的執行順序。

二、工作原理
兩種操作模式,P操作和V操作。

P操作(就是申請資源,信號量進行減一操作)

V操作(釋放資源,信號量進行加一操作)

三、 ipcs -s 查看semid

ipcrm -s id 刪除id



四、主要函數
shmget 建立信號量

shmctl 刪除

shmop P/V 操作


shmctl 刪除

shmop P/V 操作


shmctl 刪除

shmop P/V 操作

函數原型: int semop(int sem_id,struct sembuf *sops,size_t nsops);

struct sembuf *sops 參數sops指向一個結構體陣列中,每個sembuf結構體對應一個訊號的操作。結構體如下


struct sembuf
{
unsigned short sem_num;//sem_num是信号集中的索引,0代表第一个,1,代表第二个。。。 
short sem_op; //操作类型,1 -->V操作,-1-->P操作
short sem_flg; //操作标志 
 };
登入後複製

sem_flg標誌有兩種 IPC_NOWAIT 或 SEM_UNDO 兩種。如果操作指定 SEM_UNDO(我下面給的是0),它將會自動撤銷該進程在終止時。

nsops 就是sops 的個數
~~ ~~~~~~~~~~ ~~~~********** man 函數名稱可查看函數的用法******** **~~~~~~~~~~~~~~~~~~~

五、程式碼實作

comm.h

Linux--進程間通訊-信號量

#pragma once  
   #include<stdio.h>  
   #include<stdlib.h>  
   #include<unistd.h>  
   #include<sys/types.h>  
   #include<sys/ipc.h>  
   #include<sys/sem.h>  
   #define _PATH_ "."  
   #define _PROG_ID_ 0x6675  
    
   union semun  
   {  
      int val;  
      struct semid_ds *buf;   
      unsigned short *array;  
      struct seminfo *__buf;  
  };  
  int creatSem(int nsems);  
  int get_Sem();  
  int initSem(int sem_id,int Which);  
  int destroySem(int sem_id);  
  int V_Sem(int sem_id,int which);  
  int P_Sem(int sem_id,int which);  
  static int op_Sem(int sem_id,int op,int which);
登入後複製

comm.c

#include"comm.h"  
   int creatSem(int nsems)  
   {  
       key_t  _key=ftok(_PATH_,_PROG_ID_);  
       if(_key<0)  
       {  
           perror("ftok");  
           return -1;  
       }  
      umask(0);  
      int sem_Flg=IPC_CREAT|IPC_EXCL|0666;  
      int sem_id=semget(_key,nsems,sem_Flg);  
      if(sem_id<0)  
      {  
          perror("semget");  
          return -1;  
      }  
      return sem_id;  
  }  
    
  int get_Sem()  
  {  
      key_t k=ftok(_PATH_,_PROG_ID_);  
      return semget(k,0,0);  
  }  
  static int op_Sem(int sem_id,int op,int which)  
  {  
      struct sembuf sem;  
      sem.sem_num=which;  
      sem.sem_op=op;  
      sem.sem_flg=0;  
      return semop(sem_id,&sem,1);  
    
  }  
    
  int initSem(int sem_id,int Which)  
  {  
      union semun _semum;  
      _semum.val=1;  
     int ret= semctl(sem_id,Which,SETVAL,_semum);  
     if(ret==-1)  
     {  
             perror("semctl");  
             return ret;  
     }  
     return ret;  
  }  
  int P_Sem(int sem_id,int which)  
  {  
      int ret=op_Sem(sem_id,-1,which);  
      if(ret==-1)  
     {  
          perror("p_sem");  
          return -1;  
      }  
          return ret;  
    
 }  
  int V_Sem(int sem_id,int which)  
  {  
      int ret=op_Sem(sem_id,1,which);  
      if(ret==-1)  
      {  
          perror("V_Sem");  
          return ret;  
      }  
      return ret;  
  }  
    
  int destroySem(int sem_id)  
  {  
      int ret=semctl(sem_id,0,IPC_RMID,NULL);  
      if(ret==-1)  
      {  
          perror("semtrl");  
          return -1;  
      }  
      return ret;  
    
  }
登入後複製

my_shm.cLinux--進程間通訊-信號量

#include"comm.h"  
   int main()  
   {  
        int sem_id=creatSem(1);  
       initSem(sem_id,0);  
       pid_t id=fork();  
       if(id<0)  
       {  
           perror("for");  
          return -1;  
      }  
      else if(id==0)  
      {  
          int sem_id=get_Sem();  
          while(1)  
         {  
    
              P_Sem(sem_id,0);  
              printf("A");  
              fflush(stdout);  
              sleep(1);  
              printf("A");  
              fflush(stdout);  
              sleep(2);  
              V_Sem(sem_id,0);  
          }  
    
      }else  
      {  
          while(1)  
          {  
              P_Sem(sem_id,0);  
              printf("B");  
              fflush(stdout);  
              sleep(1);  
              printf("B");  
              fflush(stdout);  
              sleep(1);  
              V_Sem(sem_id,0);  
          }  
          waitpid(id,NULL,0);  
      }  
    
  }
登入後複製

在信號量之前(如下圖)可以看出列印結果是隨機的。


🎜加了信號量之後(如下圖)(都是成對出現的,因為是互斥的)🎜🎜🎜🎜🎜以上就是Linux--進程間通信信號量的內容,更多相關內容請關注PHP中文網(www.php.cn)! 🎜🎜🎜🎜
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板