Heim  >  Artikel  >  Backend-Entwicklung  >  Linux – Semaphor für die prozessübergreifende Kommunikation

Linux – Semaphor für die prozessübergreifende Kommunikation

黄舟
黄舟Original
2017-01-18 10:39:071197Durchsuche

1. Was ist ein Semaphor?
Es ist ein Zähler, der die Anzahl bestimmter Ressourcen beschreibt. Er realisiert die Prozesskommunikation, indem er andere Kommunikationsressourcen steuert. Es ist während dieses Prozesses für den gegenseitigen Datenausschluss, die Synchronisierung usw. verantwortlich. Gegenseitiger Ausschluss bedeutet, dass im gleichen Zeitraum nur ein Prozess von A und B läuft. synchron. Das heißt, nachdem Prozess A abgeschlossen ist, wird als nächstes Prozess B abgeschlossen und es gibt eine bestimmte Ausführungsreihenfolge.

2. Funktionsprinzip
Zwei Betriebsarten, P-Betrieb und V-Betrieb.

P-Operation (d. h. Ressourcen beantragen, und das Semaphor wird um eins reduziert)

V-Operation (Ressourcen freigeben, und das Semaphor wird um eins erhöht)

3. ipcs -s Semid anzeigen

ipcrm -s id ID löschen

4. Hauptfunktionen
shmget Semaphor erstellen

shmctl Löschen

shmop P/V-Betrieb

Funktionsprototyp: int semop(int sem_id,struct sembuf *sops,size_t nsops);

sem_id wird durch die shmget-Funktion erstellt

struct sembuf * sops-Parameter sops Zeigt auf ein Array von Strukturen. Jede Sembuf-Struktur entspricht einer Signaloperation. Die Struktur ist wie folgt:

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

Es gibt zwei Arten von sem_flg-Flags: IPC_NOWAIT oder SEM_UNDO. Wenn die Operation SEM_UNDO angibt (ich habe unten 0 angegeben), wird der Vorgang beim Beenden automatisch rückgängig gemacht.
nsops ist die Anzahl der sops
~~ ~~~~~~~~~~ ~~~~********** Man-Funktionsname kann die Verwendung der Funktion anzeigen** ** ******~~~~~~~~~~~~~~~~

5. Code-Implementierung
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);  
      }  
    
  }

Bevor Sie das Semaphor verwenden (wie unten gezeigt), können Sie sehen, dass das Druckergebnisse sind zufällig.

Linux – Semaphor für die prozessübergreifende Kommunikation

Nach dem Hinzufügen des Semaphors (wie unten gezeigt) (alle erscheinen paarweise, da sie sich gegenseitig ausschließen)

Linux – Semaphor für die prozessübergreifende Kommunikation

Das Obige ist der Inhalt von Linux-Inter-Process Communication-Semaphore. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn).


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn