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

//栅栏模型:实现以下框架中的四个子进程 所有进程做完任务后 在一起执行下一次  
#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("========升起栅栏=======\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);
          //随机休眠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);
}

IPC之——信号量集(多个信号量)的更多相关文章

  1. ucos信号量集源码分析

    在实际的应用之中,一个任务经常需要等待多个信号量的同时生效,或者说任务需要根据多个信号量的组合作用的结果来决定任务的运行方式,为了实现这种多信号量组合的功能,ucos实现了信号量集的特殊结构. 信号量 ...

  2. IPC之——信号量集

    信号量集用于对存在竞争的资源加锁 1.semId=semget(key,nsems,semflg) key:为信号量集名称,可以指定为0455等数字,也可以为PC_PRIVATE nsems:创建几个 ...

  3. μC/OS-II 信号量集

    简介 在实际应用中,任务常常需要与多个事件同步,即要根据多个信号量组合作用的结果来决定任务的运行方式.μC/OS-II 为了实现多个信号量组合的功能定义了一种特殊的数据结构--信号量集. 信号量集所能 ...

  4. 【iCore4 双核心板_uC/OS-II】例程十:信号量集

    一.实验说明: 在实际应用中,任务常常需要与多个事件同步,即要根据多个信号量组合作用的结果来决定任务的运行方式.UCOSII为了实现多个信号量组合的功能定义了一种特殊的数据结构——信号量集. 二.实验 ...

  5. FreeRTOS 任务计数信号量,任务二值信号量,任务事件标志组,任务消息邮箱

    以下基础内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 计数信号量的另一种实现方式----基于任务通知(Task Not ...

  6. FreeRTOS 二值信号量,互斥信号量,递归互斥信号量

    以下转载自安富莱电子: http://forum.armfly.com/forum.php 本章节讲解 FreeRTOS 任务间的同步和资源共享机制,二值信号量. 二值信号量是计数信号量的一种特殊形式 ...

  7. RT-Thread信号量使用(动态/静态信号量) 及 信号量的四种使用场合

    信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用.在进入一个关键代码段之前,线程必须获取一个信号量:一旦该关键代码段完成了 ...

  8. UCOSII笔记---信号量、邮箱、消息队列、信号量集、软件定时器

    一.接收邮箱函数的参数:timeout表示的是滴答定时器的节拍数,比如设定5ms为一个节拍,超时为100ms,则timeout=20. void *OSMboxPend (OS_EVENT *peve ...

  9. Linux进程间通信:IPC对象——信号灯集详解

    作者:倪老师,华清远见嵌入式学院讲师. 一.信号灯概述 信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制.相当于内存中的标志,进程可以根据它判定是否能够访问某些共享资源,同时 ...

随机推荐

  1. 干货 | 快速实现数据导入及简单DCS的实现

    干货 | 快速实现数据导入及简单DCS的实现 原创: 赵琦 京东云开发者社区  4月18日 对于多数用户而言,在利用云计算的大数据服务时首先要面临的一个问题就是如何将已有存量数据快捷的导入到大数据仓库 ...

  2. MSE(均方误差)、RMSE (均方根误差)、MAE (平均绝对误差)

    1.MSE(均方误差)(Mean Square Error) MSE是真实值与预测值的差值的平方然后求和平均. 范围[0,+∞),当预测值与真实值完全相同时为0,误差越大,该值越大. import n ...

  3. ElasticSearch的9200和9300端口的区别

    9200用于外部通讯,基于http协议,程序与es的通信使用9200端口. 9300jar之间就是通过tcp协议通信,遵循tcp协议,es集群中的节点之间也通过9300端口进行通信.

  4. [RoarCTF 2019]Easy Java

    0x01知识点: WEB-INF/web.xml泄露 WEB-INF主要包含一下文件或目录: /WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命 ...

  5. python中ndarray和matrix

    1. 定义ndarray和matrix from numpy import * a = mat([[1,2],[3,4]]) b = mat([[5,6],[7,8]]) c = array([1,2 ...

  6. Vue.js——1.初识Vue

    初识Vue.js 1. 什么是Vue.js Vue.js是前端主流框架之一,现在看招聘几乎都要求会vue 好像成了前端的代名词. Vue.js是构建界面 只关注视图层V,也就是页面的, 2. 为什么要 ...

  7. mqtt+htttp+websocket

    一.介绍 1.参考网址1:WebSocket协议:5分钟从入门到精通 2.参考网址2:WebSocket 教程(阮一峰) 二.应用 1.参考网址1:从 HTTP 到 MQTT:一个移动后端案例概述 2 ...

  8. 手机H5,用Jquery使图片自动填满两栏式排版

    遇上这样的排版,手机的解象度都不同,假如只用CSS3根本就做不出这样的排版:因此要用Jquery. 1. HTML <div class="postImgCenterCrop" ...

  9. 吴裕雄--天生自然ShellX学习笔记:Shell test 命令

    Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值.字符和文件三个方面的测试. 实例演示: num1=100 num2=100 if test $[num1] -eq $[num2 ...

  10. 记录华为、魅族手机无法打印 Log 日志的问题

    http://yifeng.studio/2017/02/26/android-meizu-huawei-not-log/ 实测 MEIZU PRO 6 :打开[设置]中的[开发者选项],页面底部找到 ...