【版权声明:尊重原创。转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu。文章仅供学习交流,请勿用于商业用途】
        在第一节说到了生产者消费者问题,这一节我们来实现这样一个稍作改动的模型: 初始时缓冲区为空。生产者向缓冲区写入数据。消费者在缓冲区为空的情况下睡眠,当生产者写满缓冲区一半之后后通知消费者能够開始消费。生产者開始睡眠。直到消费者消费完缓冲区一半后通知生产者能够開始生产为止,当中生产者和消费者对缓冲区的訪问时相互排斥的。
以下来看一下实现:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h> #define MAX_BUFFER 6 int buffer = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_consumer = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_productor = PTHREAD_COND_INITIALIZER; void *consumer_th(void *arg)
{ for (;;) {
pthread_mutex_lock(&mutex); if (buffer <= 0) {
printf("=%s->%d=====consumer wait productor to product, start sleep..., buffer=%d\n", __func__, __LINE__, buffer);
pthread_cond_wait(&cond_consumer, &mutex);//当消费者发现缓冲区为空时開始睡眠
} buffer--; //消费者消耗一个缓冲区
printf("=%s->%d====consumer consume a buffer, buffer=%d\n", __func__, __LINE__, buffer);
if (buffer < MAX_BUFFER/2) {
pthread_cond_signal(&cond_productor); //当消费者发现缓冲区不足一半时通知生产者開始生产
printf("=%s->%d====Notify productor...,, buffer: %d\n", __func__, __LINE__, buffer);
} pthread_mutex_unlock(&mutex); sleep(3);
} return NULL;
} void *productor_th(void *arg)
{ for (;;) {
sleep(1); pthread_mutex_lock(&mutex); if (buffer >= MAX_BUFFER) {
printf("=%s->%d=====productor wait consumer to consume, start sleep..., buffer=%d\n", __func__, __LINE__, buffer);
pthread_cond_wait(&cond_productor, &mutex);//当缓冲区满时。暂停生产
} buffer++;//生产者添加一个缓冲区
printf("=%s->%d====Product add a buffer..., buffer: %d\n", __func__, __LINE__, buffer); if (buffer > MAX_BUFFER/2) {
pthread_cond_signal(&cond_consumer);//当缓冲区添加到一半时,通知消费者能够開始消费
printf("=%s->%d====Notify consumer...,, buffer: %d\n", __func__, __LINE__, buffer);
} pthread_mutex_unlock(&mutex);
}
return NULL;
} int main(int argc, const char *argv[])
{
pthread_t tid_productor, tid_consumer; if (0 != pthread_create(&tid_consumer, NULL, consumer_th, NULL)) {
printf("pthread_create failed!\n");
return -1;
} if (0 != pthread_create(&tid_productor, NULL, productor_th, NULL)) {
printf("pthread_create failed!\n");
return -1;
} pthread_join(tid_productor, NULL);
pthread_join(tid_consumer, NULL); return 0;
}
以下是程序执行输出结果:
=consumer_th->20=====consumer wait productor to product, start sleep..., buffer=0//消费者開始睡眠等待生产者唤醒
=productor_th->54====Product add a buffer..., buffer: 1
=productor_th->54====Product add a buffer..., buffer: 2
=productor_th->54====Product add a buffer..., buffer: 3
=productor_th->54====Product add a buffer..., buffer: 4//生产者開始写缓冲区,当写到第4(超过一半)个通知消费者
=productor_th->58====Notify consumer...,, buffer: 4
=consumer_th->25====consumer consume a buffer, buffer=3//消费者一边消费缓冲区
=productor_th->54====Product add a buffer..., buffer: 4//生产者一边生产缓冲区
=productor_th->58====Notify consumer...,, buffer: 4
=productor_th->54====Product add a buffer..., buffer: 5
=productor_th->58====Notify consumer...,, buffer: 5
=consumer_th->25====consumer consume a buffer, buffer=4
=productor_th->54====Product add a buffer..., buffer: 5
=productor_th->58====Notify consumer...,, buffer: 5
=productor_th->54====Product add a buffer..., buffer: 6
=productor_th->58====Notify consumer...,, buffer: 6
=productor_th->49=====productor wait consumer to consume, start sleep..., buffer=6//当生产者生产缓冲区满时,開始睡眠
=consumer_th->25====consumer consume a buffer, buffer=5
=consumer_th->25====consumer consume a buffer, buffer=4
=consumer_th->25====consumer consume a buffer, buffer=3
=consumer_th->25====consumer consume a buffer, buffer=2//当消费者消费缓冲区到不足一半时。唤醒生产者開始生产
=consumer_th->28====Notify productor...,, buffer: 2
=productor_th->54====Product add a buffer..., buffer: 3
=productor_th->54====Product add a buffer..., buffer: 4
=productor_th->58====Notify consumer...,, buffer: 4
=productor_th->54====Product add a buffer..., buffer: 5
=productor_th->58====Notify consumer...,, buffer: 5
=consumer_th->25====consumer consume a buffer, buffer=4
=productor_th->54====Product add a buffer..., buffer: 5
=productor_th->58====Notify consumer...,, buffer: 5
=productor_th->54====Product add a buffer..., buffer: 6
=productor_th->58====Notify consumer...,, buffer: 6
=productor_th->49=====productor wait consumer to consume, start sleep..., buffer=6
本节源代码下载:

Linux相互排斥与同步应用(三):posix线程实现单个生产者和单个消费者模型的更多相关文章

  1. Linux多线程实践(六)使用Posix条件变量解决生产者消费者问题

    前面的一片文章我们已经讲过使用信号量解决生产者消费者问题.那么什么情况下我们须要引入条件变量呢? 这里借用  http://www.cnblogs.com/ngnetboy/p/3521547.htm ...

  2. Linux环境编程之同步(四):Posix信号量

    信号量是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语.有三种类型:Posix有名信号量,使用Posix IPC名字标识.Posix基于内存的信号量,存放在共享内存区中:System ...

  3. Linux多线程同步之相互排斥量和条件变量

    1. 什么是相互排斥量 相互排斥量从本质上说是一把锁,在訪问共享资源前对相互排斥量进行加锁,在訪问完毕后释放相互排斥量上的锁. 对相互排斥量进行加锁以后,不论什么其它试图再次对相互排斥量加锁的线程将会 ...

  4. 【Linux 线程】线程同步《三》

    1.条件变量 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起:另一个线程使"条件成立"(给出条 ...

  5. linux Posix线程同步(条件变量) 实例

    条件变量:与互斥量一起使用,暂时申请不到某资源时进入条件阻塞等待,当资源具备时线程恢复运行 应用场合:生产线程不断的生产资源,并通知产生资源的条件,消费线程在没有资源情况下进入条件等待,一直等到条件信 ...

  6. 多线程相互排斥--mutex(二)

    不知道大家对多线程或多进程间的同步相互排斥的控制机制了解的怎么样,事实上有非常多种方法能够实现这个目的,可是这些方法事实上由4种最主要的方法实现.这4种最主要的方法详细定义例如以下:在这有讲得不正确的 ...

  7. 多线程相互排斥--mutex

    多线程之线程同步Mutex (功能与Critial Sections同样,可是属于内核对象,訪问速度较慢.能够被不同进程调用) 一 Mutex     相互排斥对象(mutex)内核对象可以确保线程拥 ...

  8. POSIX 线程具体解释(3-相互排斥量:"固定加锁层次"/“试加锁-回退”)

    有时一个相互排斥量是不够的: 比方: 当多个线程同一时候訪问一个队列结构时,你须要2个相互排斥量,一个用来保护队列头,一个用来保护队列元素内的数据. 当为多线程建立一个树结构时.你可能须要为每一个节点 ...

  9. Linux环境编程之同步(二):条件变量

    相互排斥锁用于上锁,条件变量则用于等待.条件变量是类型为pthread_cond_t的变量.一般使用例如以下函数: #include <pthread.h> int pthread_con ...

随机推荐

  1. PAT 天梯赛 L1-043 阅览室

    L1-043. 阅览室 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 天梯图书阅览室请你编写一个简单的图书借阅统计程序.当读者 ...

  2. JavaScript中in的用法

    JavaScript中的in 操作符是对Object(对象)操作的,并不是针对数组. in 的右边必须是对象变量 例如:var data = {id:1, name:'AAA'};if('name' ...

  3. 用Razor来生成模板 using razor for template

    原文发布时间为:2011-09-15 -- 来源于本人的百度文章 [由搬家工具导入] http://razorengine.codeplex.com/

  4. 利用GridView控件导出其他文件(导出Excel,导出Word文件)

    原文发布时间为:2008-10-16 -- 来源于本人的百度文章 [由搬家工具导入] // 注意,在Visual Studio2005平台下,如果使用GridView导出文件,      //就必须重 ...

  5. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---34

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  6. IPC最快的方式----共享内存(shared memory)

    在linux进程间通信的方式中,共享内存是一种最快的IPC方式.因此,共享内存用于实现进程间大量的数据传输,共享内存的话,会在内存中单独开辟一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限 ...

  7. 安卓edittext实现输入数字限制条件的效果

    我们知道edittext能指定输入字符类型,这次我们就来了解下在数字模式下的一些显示控制输入的效果 1.限制输入数字 android:inputType="number|numberDeci ...

  8. HDU 6249 Alice’s Stamps(2017 CCPC-Final G题,DP)

    题目链接 HDU 6249 题意 给定$m$个区间,在这些区间中选出不超过$k$个,求被覆盖的点的数量的最大值. 设$f[i][j]$表示选到第$i$个点并选了$j$个区间的时候能得到的最大答案. 处 ...

  9. 提升开发效率的一款mybatis开发神器

    文末附有完整案例的代码内容!! 以前在开发的时候,使用mybatis的时候,经常都需要先配置xml映射文件,然后每条sql操作都需要自己进行手动编写,对于一些复杂的sql这么来操作确实有必要,但是如果 ...

  10. 洛谷——P1690 贪婪的Copy

    P1690 贪婪的Copy 题目描述 Copy从卢牛那里听说在一片叫yz的神的领域埋藏着不少宝藏,于是Copy来到了这个被划分为个区域的神地.卢牛告诉了Copy这里共有个宝藏,分别放在第Pi个(1&l ...