#include <stdio.h>  

#include <pthread.h>  

#define BUFFER_SIZE 16 // 缓冲区数量  

    struct prodcons  

    {  

        // 缓冲区相关数据结构  

        int buffer[BUFFER_SIZE]; /* 实际数据存放的数组*/  

        pthread_mutex_t lock; /* 相互排斥体lock 用于对缓冲区的相互排斥操作 */  

        int readpos, writepos; /* 读写指针*/  

        pthread_cond_t notempty; /* 缓冲区非空的条件变量 */  

        pthread_cond_t notfull; /* 缓冲区未满的条件变量 */  

    };  

    /* 初始化缓冲区结构 */  

    void init(struct prodcons *b)  

    {  

        pthread_mutex_init(&b->lock, NULL);  

        pthread_cond_init(&b->notempty, NULL);  

        pthread_cond_init(&b->notfull, NULL);  

        b->readpos = 0;  

        b->writepos = 0;  

    }  

    /* 将产品放入缓冲区,这里是存入一个整数*/  

    void put(struct prodcons *b, int data)  

    {  

        pthread_mutex_lock(&b->lock);  

        /* 等待缓冲区未满*/  

        if ((b->writepos + 1) % BUFFER_SIZE == b->readpos)  

        {  

            pthread_cond_wait(&b->notfull, &b->lock);  

        }  

        /* 写数据,并移动指针 */  

        b->buffer[b->writepos] = data;  

        b->writepos++;  

        if (b->writepos >= BUFFER_SIZE)  

            b->writepos = 0;  

        /* 设置缓冲区非空的条件变量*/  

        pthread_cond_signal(&b->notempty);  

        pthread_mutex_unlock(&b->lock);  

    }   

    /* 从缓冲区中取出整数*/  

    int get(struct prodcons *b)  

    {  

        int data;  

        pthread_mutex_lock(&b->lock);  

        /* 等待缓冲区非空*/  

        if (b->writepos == b->readpos)  

        {  

            pthread_cond_wait(&b->notempty, &b->lock);  

        }  

        /* 读数据,移动读指针*/  

        data = b->buffer[b->readpos];  

        b->readpos++;  

        if (b->readpos >= BUFFER_SIZE)  

            b->readpos = 0;  

        /* 设置缓冲区未满的条件变量*/  

        pthread_cond_signal(&b->notfull);  

        pthread_mutex_unlock(&b->lock);  

        return data;  

    }  

      

      

    /* 測试:生产者线程将1 到10000 的整数送入缓冲区,消费者线

       程从缓冲区中获取整数,两者都信息打印*/  

    #define OVER ( - 1)  

    struct prodcons buffer;  

    void *producer(void *data)  

    {  

        int n;  

        for (n = 0; n < 50; n++)  

        {  

            printf("%d ---producer==>\n", n);  

            put(&buffer, n);  

        } put(&buffer, OVER);  

        return NULL;  

    }  

      

      

    void *consumer(void *data)  

    {  

        int d;  

        while (1)  

        {  

            d = get(&buffer);  

            if (d == OVER)  

                break;  

            printf("---consumer==>%d \n", d);  

        }  

        return NULL;  

    }  

      

      

    int main(void)  

    {  

        pthread_t th_a, th_b;  

        void *retval;  

        init(&buffer);  

        /* 创建生产者和消费者线程*/  

        pthread_create(&th_a, NULL, producer, 0);  

        pthread_create(&th_b, NULL, consumer, 0);  

        /* 等待两个线程结束*/  

        pthread_join(th_a, &retval);  

        pthread_join(th_b, &retval);  

        return 0;  

    }

一个经典的消费者和生产者的实现(linux )的更多相关文章

  1. Linux 进程间通信(包含一个经典的生产者消费者实例代码)

    前言:编写多进程程序时,有时不可避免的需要在多个进程之间传递数据,我们知道,进程的用户的地址空间是独立,父进程中对数据的修改并不会反映到子进程中,但内核是共享的,大多数进程间通信方式都是在内核中建立一 ...

  2. Java程序设计之消费者和生产者

    新建一个Break类,表示食物数量. public class Break { public static final int MAX = 10; //最多一次性煮十个面包 Stack<Inte ...

  3. java多线程-消费者和生产者模式

    /* * 多线程-消费者和生产者模式 * 在实现消费者生产者模式的时候必须要具备两个前提,一是,必须访问的是一个共享资源,二是必须要有线程锁,且锁的是同一个对象 * */ /*资源类中定义了name( ...

  4. Java多线程消费者、生产者的基本思路

    多线程主要考察的就是 线程的同步控制   生产者消费者的思路就是,当 一个线程执行时让另一个线程 挂起就行了 ThreadOne.ThreadTwo同时运行,添加一个变量在一个公共类(下边的Funct ...

  5. python_并发编程——消费者和生产者模型

    消费者和生产者模型 from multiprocessing import Process,Queue import time import random class Producer(Process ...

  6. springcloud 实现简单的 消费者和生产者 模式(Restfule 的风格)

    一.springcloud 实现简单的 消费者和生产者 模式(Restfule 的风格) 1.实现简单的消费者和生产者 springcloud使用的http协议进行传输数据,也就是说springclo ...

  7. [一个经典的多线程同步问题]解决方案一:关键段CS

    前面提出了一个经典的多线程同步互斥问题,本篇将用关键段CRITICAL_SECTION来尝试解决这个问题. 本文先介绍如何使用关键段,然后再深层次的分析下关键段的实现机制和原理. 关键段CRITICA ...

  8. 用Python设计一个经典小游戏

    这是关于Python的第9篇文章,介绍如何用Python设计一个经典小游戏:猜大小. 在这个游戏中,将用到前面我介绍过的所有内容:变量的使用.参数传递.函数设计.条件控制和循环等,做个整体的总结和复习 ...

  9. 原来这是一个经典面试题-------Day61

    前几天在table的操作中,记录了动态生成表格的三种方式: 1.html语言的拼接:用字符串或者数组拼接在html语言中,这个理解起来最直观 2.插入行和列:insertRow()和insertCel ...

随机推荐

  1. Java编程思想读书笔记_第6章(访问权限)

    四种访问权限: public private 包访问权限 protected 如果没有明确指定package,则属于默认包 package access.dessert; public class C ...

  2. ES6十大常用特性

    .   Default Parameters(默认参数) in ES6 2.    Arrow Functions (箭头函数)in ES6 3.    Block-Scoped Constructs ...

  3. 全志A33平台编译linux(分色排版)sina33

    全志A33平台编译linux 大文实验室/大文哥 壹捌陆捌零陆捌捌陆捌贰 21504965 AT qq.com 完成时间:2017/12/12 17:36 版本:V1.0 Xshell 5 (Buil ...

  4. Ubuntu下查看服务器cpu是否支持VT

    http://blog.51cto.com/zhangmingqian/1249522 Ubuntu下查看服务器cpu是否支持VT 原创wazjajl 2013-07-15 16:25评论(0)119 ...

  5. 2) 十分钟学会android--建立第一个APP,执行Android程序

    通过上一节课创建了一个Android的Hello World项目,项目默认包含一系列源文件,它让我们可以立即运行应用程序. 如何运行Android应用取决于两件事情:是否有一个Android设备和是否 ...

  6. 【windows】自动化测试持续集成(CI)环境部署

    1. 环境准备 1.1 我的环境 1.Win10 64位 2.JDK 1.8.0_121 3.Tomcat 7.0.92 4. Jenkins 2.24 5.SVN-Server 3.8.1 1.2 ...

  7. jmeter接口测试小结

    摘自:http://www.cnblogs.com/houzhizhe/p/6839736.html JMeter做http接口压力测试 测前准备 用JMeter做接口的压测非常方便,在压测之前我们需 ...

  8. SpringMVC接收多参数的处理方法

    问题:依赖SpringMVC自带的机制解析多对象参数往往出现解析不了的问题,使用较为复杂. 解决思路:前端 JS 先把传递到后台的对象转换为 JSON 字符串,后台直接使用字符串类型接收,再使用 st ...

  9. JavaScript 中实现 sleep

    来自推特上 Windows 故障分析的笑话 图片来源:me.me 推上看到的笑话,Windows 故障分析的实现. 然后想起来 JavaScript 中如何实现这个 sleep() 函数让代码暂停指定 ...

  10. Python学会之后,一般能拿到多少工资?

    Python在约40年前出现以来,已经有数以千计基于这项技术的网站和软件项目,Python因其独有的特点从众多开发语言中脱颖而出,深受世界各地的开发者喜爱. 随着Python的技术的流行,Python ...