Home  >  Article  >  Backend Development  >  Linux--inter-process communication-semaphore

Linux--inter-process communication-semaphore

黄舟
黄舟Original
2017-01-18 10:39:071227browse

1. What is a semaphore?
It is a counter used to describe the number of certain resources, and realizes process communication by controlling other communication resources. It is responsible for data mutual exclusion, synchronization, etc. during this process. Mutual exclusion means that only one process of A and B is running during the same time period. Synchronize. That is, after process A is completed, process B is completed next, and there is a certain execution order.

2. Working principle
Two operating modes, P operation and V operation.

P operation (that is, apply for resources, and the semaphore is reduced by one)

V operation (release resources, and the semaphore is increased by one)

3. ipcs -s View semid

ipcrm -s id Delete id

4. Main functions
shmget Create semaphore

shmctl Delete

shmop P/V operation

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

sem_id is created through the shmget function

struct sembuf *sops parameter sops Points to an array of structures, each sembuf structure corresponds to a signal operation. The structure is as follows

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

sem_flg flag has two types: IPC_NOWAIT or SEM_UNDO. If the operation specifies SEM_UNDO (I gave it 0 below), it will automatically undo the process on termination.
nsops is the number of sops
~~ ~~~~~~~~~~~~~~********** Man function name can view the usage of the function**** ******~~~~~~~~~~~~~~~~~~~

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

Before using the semaphore (as shown below), you can see that the printing results are random.

Linux--inter-process communication-semaphore

After adding the semaphore (as shown below) (they all appear in pairs because they are mutually exclusive)

Linux--inter-process communication-semaphore

The above is the content of Linux--Inter-process Communication-Semaphore. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn