>백엔드 개발 >PHP 튜토리얼 >Linux-프로세스 간 통신-세마포어

Linux-프로세스 간 통신-세마포어

黄舟
黄舟원래의
2017-01-18 10:39:071249검색

1. 세마포어란 무엇인가요?
특정 자원의 수를 기술하는 데 사용되는 카운터입니다. 다른 통신 자원을 제어하여 프로세스 통신을 구현합니다. 이 과정에서 데이터 상호 배제, 동기화 등을 담당합니다. 상호 배제란 동일한 기간 동안 A와 B 중 하나의 프로세스만 실행된다는 의미입니다. 동기. 즉, A 프로세스가 완료된 후 다음에는 B 프로세스가 완료되며, 일정한 실행 순서가 있습니다.

2. 작동 원리
P 작동과 V 작동의 두 가지 작동 모드.

P 연산(즉, 자원을 신청하고 세마포어를 1만큼 감소)

V 연산(자원을 해제하고 세마포어를 1만큼 증가)

3. ipcs -s 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의 두 가지 유형이 있습니다. 작업이 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-Inter-Process Communication-Semaphore 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.