信号量实现环形buff下多生产者多消费者模型

posix下定义了一个semaphore,他和systemV版本下的sem很像,而这个多用于线程,它的单位是信号量,而sem的单位是信号量集。

 #include <semaphore.h>

 int sem_init(sem_t *sem, int pshared, unsigned int value);
 int sem_destroy(sem_t *sem);
 int sem_wait(sem_t *sem);
 int sem_trywait(sem_t *sem);
 int sem_post(sem_t *sem);

其中wait就是P操作,post则是V操作。

环形BUFF的设计思想:

用一个大小为BUFF_MAX的数组,生产者在前,消费者在后,生产者的pro_sem初始化BUFF_MAX,

消费者cons_sem初始化为0,生产者生产则pro_sem执行p操作cons_sem执行V操作,反之消费者消费cons_sem-1,而pro_sem+1,数组下表%BUFF_MAX这样数组就相当于一个环形BUUF了。

  1 #include<stdio.h>
  2 #include<semaphore.h>
  3 #include<pthread.h>
  4 #define PRO_BUFF 20
  5 #define CONS_BUFF 0
  6 int my_buff[PRO_BUFF];
  7 sem_t productor_sem;
  8 sem_t consumer_sem;
  9 sem_t cons_comm;
 10 sem_t pro_comm;
 11 
 12 void*productor(void *arg)
 13 {
 14     pthread_detach(pthread_self());
 15     int p=0;
 16     while(1)
 17     {
 18         sem_wait(&productor_sem);
 19         sem_wait(&pro_comm);
 20         int value=rand()%100;
 21         my_buff[p]=value;
 22         printf("productor%dalready :%d\n",(int)arg,value);
 23         sem_post(&pro_comm);
 24         sem_post(&consumer_sem);
 25         p=(p+1)%PRO_BUFF;
 26         sleep(rand()%3);
 27     }
 28 }
 29 void*consumer(void *arg)
 30 {
 31     pthread_detach(pthread_self());
 32     int c=0;
 33     while(1)
 34     {
 35         sem_wait(&consumer_sem);
 36         sem_wait(&cons_comm);
 37         int value=my_buff[c];
 38         printf("consumer%dreceive value :%d\n",(int)arg,value);
 39         sem_post(&cons_comm);
 40         sem_post(&productor_sem);
 41         c=(c+1)%PRO_BUFF;
 42         sleep(rand()%5);
 43     }
 44 
 45 }
 46 
 47 
 48 int main()
 49 {
 50     sem_init(&productor_sem,0,PRO_BUFF);
 51     sem_init(&consumer_sem,0,CONS_BUFF);
 52     sem_init(&cons_comm,0,1);
 53     sem_init(&pro_comm,0,1);
 54     pthread_t productor1_id;
 55     pthread_t consumer1_id;
 56     int i;
 57     for(i=1;i<4;i++)
 58     {
 59         pthread_create(&productor1_id,NULL,productor,(void*)i);
 60 
 61     }
 62     for(i=1;i<4;i++)
 63     {
 64         pthread_create(&consumer1_id,NULL,consumer,(void*)i);
 65     }
 66     pthread_join(productor1_id,NULL);
 67     pthread_join(consumer1_id,NULL);
 68 }

在消费者和消费者之间添加一把锁,生产者生产者之间添加一把锁,目的是为了它们之间的互斥关系。

时间: 2024-12-14 11:26:24

信号量实现环形buff下多生产者多消费者模型的相关文章

生产者、消费者模型

转载地址:http://blog.csdn.net/snow_5288/article/details/72794306 一.概念引入 日常生活中,每当我们缺少某些生活用品时,我们都会去超市进行购买,那么,你有没有想过,你是以什么身份去的超市呢?相信大部分人都会说自己是消费者,确实如此,那么既然我们是消费者,又是谁替我们生产各种各样的商品呢?当然是超市的各大供货商,自然而然地也就成了我们的生产者.如此一来,生产者有了,消费者也有了,那么将二者联系起来的超市又该作何理解呢?诚然,它本身是作为一座交

并发无锁队列学习(单生产者单消费者模型)

1.引言 本文介绍单生产者单消费者模型的队列.根据写入队列的内容是定长还是变长,分为单生产者单消费者定长队列和单生产者单消费者变长队列两种.单生产者单消费者模型的队列操作过程是不需要进行加锁的.生产者通过写索引控制入队操作,消费者通过读索引控制出队列操作.二者相互之间对索引是独享,不存在竞争关系.如下图所示: 2.单生产者单消费者定长队列 这种队列要求每次入队和出队的内容是定长的,即生产者写入队列和消费者读取队列的内容大小事相同的.linux内核中的kfifo就是这种队列,提供了读和写两个索引.

单生产者-多消费者模型中遇到的问题

(1)      原始代码 最近使用单生产者-多消费者模型是遇到一个问题,以前既然都没有想到过.生产者线程的代码如下,基本功能就是接收到一个连接之后创建一个Socket对象并放到list中等待处理. void DataManager::InternalStart() { server_socket_ = new ServerSocket(); if (!server_socket_->SetAddress(NetworkUtil::GetIpAddress().c_str(), 9091)) {

开启子进程的两种方式,孤儿进程与僵尸进程,守护进程,互斥锁,IPC机制,生产者与消费者模型

开启子进程的两种方式 # # # 方式一: # from multiprocessing import Process # import time # # def task(x): # print('%s is running' %x) # time.sleep(3) # print('%s is done' %x) # # if __name__ == '__main__': # # Process(target=task,kwargs={'x':'子进程'}) # p=Process(tar

守护进程,互斥锁,IPC,队列,生产者与消费者模型

小知识点:在子进程中不能使用input输入! 一.守护进程 守护进程表示一个进程b 守护另一个进程a 当被守护的进程结束后,那么守护进程b也跟着结束了 应用场景:之所以开子进程,是为了帮助主进程完成某个任务,然而,如果主进程认为自己的事情一旦做完了就没有必要使用子进程了,就可以将子进程设置为守护进程 例如:在运行qq的过程,开启一个进程,用于下载文件,然而文件还没有下载完毕,qq就退出了,下载任务也应该跟随qq的退出而结束. from multiprocessing import Process

Go语言编程:使用条件变量Cond和channel通道实现多个生产者和消费者模型

如题,使用条件变量Cond和channel通道实现多个生产者和消费者模型.Go语言天生带有C语言的基因,很多东西和C与很像,但是用起来 绝对比C语言方便.今天用Go语言来实现下多消费者和生产者模型.如果对C语言的多生产者和消费者模型感兴趣的可以看Linux系统编程:使用mutex互斥锁和条件变量实现多个生成者和消费者模型 代码实现代码实现用了Cond条件变量和channel通道. package main import ( "fmt" "math/rand" &qu

Java线程学习整理--4---一个简单的生产者、消费者模型

 1.简单的小例子: 下面这个例子主要观察的是: 一个对象的wait()和notify()使用情况! 当一个对象调用了wait(),那么当前掌握该对象锁标记的线程,就会让出CPU的使用权,转而进入该对象的等待池中等待唤醒,这里说明一下,每一个对象都有一个独立的等待池和锁池! 等待池:上述的wait()后的线程会进入等待池中,处于下图线程声明周期(简单示意图) 中的这个状态,等待池中的线程任然具有对象的锁标记,但是处于休眠状态,不是可运行状态! 当该对象调用notify方法之后,就会在等待池中系统

Java并发协作——生产者、消费者模型

概述 对于多线程程序来说,生产者和消费者模型是非常经典的模型.更加准确的说,应该叫"生产者-消费者-仓库模型".离开了仓库,生产者.消费者就缺少了共用的存储空间,也就不存在并非协作的问题了. 示例 定义一个场景.一个仓库只允许存放10件商品,生产者每次可以向其中放入一个商品,消费者可以每次从其中取出一个商品.同时,需要注意以下4点: 1.  同一时间内只能有一个生产者生产,生产方法需要加锁synchronized. 2.  同一时间内只能有一个消费者消费,消费方法需要加锁synchro

并发协作:多线程中的生产者与消费者模型

对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一样,Hello World!都是最经典的例子. 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了. 对于此模型,应该明确一下几点: 1.生产者仅仅在仓储未满时候生产,仓满则停止生产. 2.消费者仅仅在仓储有产品时候才能消费,仓空则等待. 3.当消费者发现仓储没产品可消费时候会通知生产者生产. 4.生产者在生产出可消费产品时候,应该通知等待的消费者去消费.