ホームページ  >  記事  >  バックエンド開発  >  Linux--プロセス間通信セマフォ

Linux--プロセス間通信セマフォ

黄舟
黄舟オリジナル
2017-01-18 10:39:071229ブラウズ

1. セマフォとは 他の通信リソースを制御することで、プロセス通信を実現するためのカウンターです。このプロセス中のデータの相互排除、同期などを担当します。相互排他とは、同じ期間中に A と B の 1 つのプロセスだけが実行されることを意味します。同期します。つまり、処理 A が完了すると、次に処理 B が完了するという順序があり、実行には順序があります。

2.動作原理
2つの動作モード、P動作とV動作。

P 操作 (つまり、リソースを申請し、セマフォが 1 つ減ります)

V 操作 (リソースを解放し、セマフォが 1 つ増加します)

3. semid

ipcrm を表示します - s id idの削除

4. 主な関数
shmget セマフォの作成

shmctl 削除

shmop P/V演算

関数プロトタイプ: int semop(int sem_id,struct sembuf *sops,size_t nsops);

sem_id作成されましたshmget 関数を使用して

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の2種類あります。操作で SEM_UNDO が指定されている場合 (以下では 0 を指定しています)、終了時にプロセスが自動的に元に戻されます。

nsops は SOPS の数です
~~ ~~~~~~~~~~ ~~~~************ Man 関数名は関数の使用法を表示できます**** ****** **~~~~~~~~~~~~~~~~~~~

5. コード実装
comm.h

#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。 c


#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--プロセス間通信セマフォ

セマフォを追加した後(以下に示すように)(相互に排他的であるため、すべてペアで表示されます)

Linux--プロセス間通信セマフォ

上記は、Linux-プロセス間通信-セマフォの内容であり、さらに関連することに注意してくださいコンテンツについては、PHP 中国語 Web サイト (www.php.cn) をご覧ください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。