基于POSIX的信号量的生产者消费者模型

信号量和Mutex类似,表示可用资源的数量,和Mutex不同的是,这个数量可以大于1,即如果信号量描述的资源数目是1时,此时的信号量和互斥锁相同。

下面我们看看POSIX semaphore库函数,它既可以用于同一进程的线程间同步,也可以用于不同进程间的同步。

1. int sem_init(sem_t *sem,int pshared,unsigned int value)

我们可以用此函数来创建一个未命名的信号量,pshared参数表明是否在多个进程中使用信号量,如果是,将其设置为非0 值,value参数制定了信号量的初始值。

2.int sem_destroy(sem_t *sem)

当我们对未命名的信号量使用已完成时,可以调用sem_destroy函数丢弃它。调用sem_destroy后,不能再使用任何带有sem的信号量函数,除非通过调用sem_init重新初始化它。

3.int sem_wait(sem_t *sem)

int sem_trywait(sem_t *sem)

我们可以使用sem_wait或者sem_trywait函数来实现信号量的减1操作。使用sem_wait函数时,如果信号量计数是0,就会发生阻塞。直到成功使信号量减1或者被信号中断时才返回。可以使用sem_trywait来避免阻塞。调用sem_trywait时,如果信号量是0,则不会阻塞,而是会返回-1,并将errno置为EAGAIN.

4.int sem_post(sem_t *sem)

我们可以调用它是信号量增1.

下面我们来看一段基于信号量的生产者消费者模型:

#include <stdio.h>
   #include <stdlib.h>
   #include <pthread.h>
   #include <semaphore.h>
   
   #define _SIZE_ 20
   int buf[_SIZE_];
   sem_t blank;
   sem_t data;
  
  void *product(void *arg)
  {
      int index=0;
      int count=0;
      while(1)
      {
          sem_wait(&blank);//P
          buf[index]=count++;
          sleep(2);
          sem_post(&data);//V
          index++;
          index %= _SIZE_;
      }
  }
  
  void *consumer(void *arg)
  {
      int index=0;
      int count=0;
      while(1)
      {
          sem_wait(&data);
          count=buf[index];                                                                                                                                           
          printf("consumer data:%d\n",count);
          sem_post(&blank);
          index++;

index %= _SIZE_;
      }
  }
                                                                                                                                                           
  int main()
  {
      sem_init(&blank,0,_SIZE_);
      sem_init(&data,0,0);
  
      pthread_t tid1,tid2;
      pthread_create(&tid1,NULL,product,NULL);
      pthread_create(&tid2,NULL,consumer,NULL);
  
      pthread_join(tid1,NULL);
      pthread_join(tid2,NULL);
  
      sem_destroy(&blank);
      sem_destroy(&data);
      return 0;
  }

运行结果如下:

我们可以看到消费者在不停的消费生产者生产的数据、、、、、

				
时间: 2024-12-30 12:57:42

基于POSIX的信号量的生产者消费者模型的相关文章

【Windows】用信号量实现生产者-消费者模型

线程并发的生产者-消费者模型: 1.两个进程对同一个内存资源进行操作,一个是生产者,一个是消费者. 2.生产者往共享内存资源填充数据,如果区域满,则等待消费者消费数据. 3.消费者从共享内存资源取数据,如果区域空,则等待生产者填充数据. 4.生产者的填充数据行为和消费者的消费数据行为不可在同一时间发生. 下面用Windows的信号量以及线程等API模拟生产者-消费者模型 #include <Windows.h> #include <stdio.h> #define N 100 #d

Linux下用环形buf以及POSIX版本信号量解决生产者消费者问题

一.Semaphore(信号量) Mutex变量是非0即1的,可看作一种资源的可用数量,初始化时Mutex是1,表示有一个可用资源, 加锁时获得该资源,将Mutex减到0,表示不再有可用资源,解锁时释放该资源,将Mutex重新加到1,表示又有了一个可用资源. 信号量(Semaphore)和Mutex类似,表示可用资源的数量,和Mutex不同的是这个数量可以大于1. 即,如果信号量描述的资源数目是1时,此时的信号量和互斥锁相同! 本次使用的是POSIX semaphore库函数,这种信号量不仅可以

生产者/消费者模型

http://www.cnblogs.com/xrq730/p/4855663.html 什么是生产者/消费者模型 一种重要的模型,基于等待/通知机制.生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几个点: 1.生产者生产的时候消费者不能消费 2.消费者消费的时候生产者不能生产 3.缓冲区空时消费者不能消费 4.缓冲区空时生产者不能生产 生产者/模型作为一种重要的模型,它的优点在于: 1.解耦.因为多了一个缓冲区

Java多线程14:生产者/消费者模型

什么是生产者/消费者模型 一种重要的模型,基于等待/通知机制.生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几个点: 1.生产者生产的时候消费者不能消费 2.消费者消费的时候生产者不能生产 3.缓冲区空时消费者不能消费 4.缓冲区满时生产者不能生产 生产者/模型作为一种重要的模型,它的优点在于: 1.解耦.因为多了一个缓冲区,所以生产者和消费者并不直接相互调用,这一点很容易想到,这样生产者和消费者的代码发生变化,

Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型

一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例子 #并发运行,效率高,但竞争同一打印终端,带来了打印错乱 from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('

11.python并发入门(part8 基于线程队列实现生产者消费者模型)

一.什么是生产者消费者模型? 生产者就是生产数据的线程,消费者指的就是消费数据的线程. 在多线程开发过程中,生产者的速度比消费者的速度快,那么生产者就必须等待消费者把数据处理完,生产者才会产生新的数据,相对的,如果消费者处理数据的速度大于生产者,那么消费者就必须等待生产者. 为了解决这种问题,就有了生产者消费者模型. 生产者与消费者模型,是通过一个容器,来解决生产者和消费者之间的耦合性问题,生产者和消费者之间并不会直接通信,这样生产者就无需等待消费者处理完数据,生产者可以直接把数据扔给队列,这个

13 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件  queue队列 生产者消费者模型 Queue队列 开发一个线程池

本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池 操作系统发展史 手工操作(无操作系统) 1946年第一台计算机诞生--20世纪50年代中期,还未出现操作系统,计算机工作采用手工操作方式. 手工操作程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入输入机,然后启动输入机把

基于go的生产者消费者模型

基于go的生产者消费者模型 //生产者 func Producer(ch chan int) { for i := 1; i <= 10; i++ { ch <- i } close(ch) } //消费者 func Consumer(id int, ch chan int, done chan bool) { for { value, ok := <-ch if ok { fmt.Printf("id : %d consum %d value \n", id, va

浅谈生产者消费者模型与读写者模型的区别

多线程编程在操作系统中是十分重要的. 而在线程中处理同步与互斥问题又是至关重要的.生产者-消费者模型,(也称有限缓冲问题)是一个多线程同步问题的经典例子.下来我们对其进行简单分析. 生产者-->生成一定量的数据放到缓冲区中,然后重复此过程: 消费者-->在缓冲区消耗这些数据. 而生产者-消费者之间存在三种关系,即 生产者与生产者之间是互斥关系: 消费者与消费者之间是互斥关系: 生产者与消费者之间是同步与互斥关系. 下面的程序演示了一个生产者-消费者的例子,生产者生产一个结构体串在链表的表头上,