IPC - semaphore set (multiple semaphores)

If two processes not only need to be synchronized, but also to ensure the order of execution, it is necessary to use two semaphores (mutual exclusion locks) to solve the problem.

//Fence model: Implement the four subprocesses in the following framework. After all processes complete their tasks, they will execute the next time together  
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include < sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <signal.h>

#define PROCESS_NR 4
void sigFunc(int signo)
{
    int semId;
    semId=semget(0x555,PROCESS_NR+1,IPC_CREAT|0600);
    if(semId>0){
       semctl(semId,0,IPC_RMID);
    }
    exit(1);
}

void p_lock(int idx,int semId);
void waitZero(int semId);

void doWork(int idx,int semId);

int main(void)
{
     int semId,i;
     pid_t pid;
     //////////////////////////////
     //The corresponding subscript semaphore controls the last one of the corresponding child process Semaphore control parent process
     semId=semget(0x555,PROCESS_NR+1,IPC_CREAT|0600);
     if(semId==-1)
     {
         perror("create sem");
         return 11;
     }
     //init sem value
    unsigned short vals[ PROCESS_NR+1]={0}; //Initialize multiple semaphore values
     ​​if(semctl(semId,0,SETALL,vals)==-1)
     {
          perror("init sem val");
          semctl(semId, 0,IPC_RMID);
          return 12;
     }
     /////////////////////////////
     for(i=0;i<PROCESS_NR ;i++)
     {
          pid=fork();
          if(pid==-1) return 1;
          else if(pid==0)//child process
          {
              doWork(i,semId);//i identifies the number of the process
              exit(0);
          }
     }
     //
     signal(SIGINT ,sigFunc);
     //parent
    struct sembuf bufs[PROCESS_NR+1]={0};
     for(i=0;i<PROCESS_NR;i++)// Subprocess
     {
          bufs[i].sem_num=i;
          bufs[i] .sem_op =1;
     }
     bufs[PROCESS_NR].sem_num=PROCESS_NR;//Father's resource
     bufs[PROCESS_NR].sem_op =PROCESS_NR;

     //////////////////// //////////////////
     while(1)
     {
          waitZero(semId);
          printf("========Raise the fence========\n");
          semop(semId,bufs,PROCESS_NR+1);
     }

     while(wait(NULL)!=-1)
        ; //empty
     return 0;
}
void doWork(int idx,int semId)
{
      pid_t pid=getpid();
      int sec;

      srand(pid);

      while(1)
      {
          p_lock(idx,semId);

          sec=rand()% 10+1;
          printf("%dth Do [%d] sec:%d\n",idx,pid,sec);
          //Sleep randomly for 1-10s, simulating different processes and doing things at different times may require different
          sleep durations (sec);

          //Notify the parent process that the child process has finished
          executing p_lock(PROCESS_NR,semId);
      }
}

////////////////////////// /////////////
void p_lock(int idx,int semId)
{
      struct sembuf  buf={.sem_num=idx,.sem_op=-1};

      semop(semId,&buf,1);
}
void waitZero(int semId)
{
      struct sembuf  buf={.sem_num=PROCESS_NR,.sem_op=0};

      semop(semId,&buf,1);
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324778000&siteId=291194637
IPC