zoukankan      html  css  js  c++  java
  • IPC之——信号量集(多个信号量)

    如果两个进程不仅需要同步,还要保证先后执行顺序,就要用两个信号量(互斥锁)来解决

    //栅栏模型:实现以下框架中的四个子进程 所有进程做完任务后 在一起执行下一次  
    #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;
         ////////////////////////////////
         //对应的下标的信号量控制对应的子进程  最后一个信号量控制父进程
         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};//对多个信号量值进行初始化
         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标识进程的编号
                  exit(0);
              }
         }
         //
         signal(SIGINT,sigFunc);
         //parent
         struct sembuf  bufs[PROCESS_NR+1]={0};
         for(i=0;i<PROCESS_NR;i++)//子进程
         {
              bufs[i].sem_num=i;
              bufs[i].sem_op =1;
         }
         bufs[PROCESS_NR].sem_num=PROCESS_NR;//父亲的资源
         bufs[PROCESS_NR].sem_op =PROCESS_NR;

         ////////////////////////////////////////
         while(1)
         {
              waitZero(semId);
              printf("========升起栅栏======= ");
              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 ",idx,pid,sec);
              //随机休眠1-10s 模拟不同进程不同时侯做事情可能需要不同的时长
              sleep(sec);

              //通知父进程 该子进程已执行完毕
              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);
    }

  • 相关阅读:
    利用docker搭建RTMP直播流服务器实现直播
    基于.NET平台的Ocelot网关框架教程汇总
    docker swarm集群搭建及使用Portainer、shipyard
    Swarm 集群并用 Portainer 管理
    如何在Debian 9上安装和使用Docker
    人不成熟的五大特征:立即要回报、不自律、经常被情绪所左右、不愿学习、做事情不靠信念靠人言(你中了几条?)
    使用 xpath helper 提取网页链接
    Python 爬虫js加密破解(四) 360云盘登录password加密
    Python 爬虫js加密破解(三) 百度翻译 sign
    Python 获得最近一个月的每天的日期
  • 原文地址:https://www.cnblogs.com/edan/p/8932306.html
Copyright © 2011-2022 走看看