#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 8 (7) 重构、测试和调试

    为改善可读性和灵活性重构代码 看到这里我们已经可以使用lambda和stream API来使代码更简洁,用在新项目上.但大多数并不是全新的项目,而是对现有代码的重构,让它变的更简洁可读,更灵活. 改善 ...

  2. HTML空格占位

      它叫不换行空格,全称No-Break Space,它是最常见和我们使用最多的空格,大多数的人可能只接触了 ,它是按下space键产生的空格.在HTML中,如果你用空格键产生此空格,空格是不会累加的 ...

  3. 动态调用链接库(dll) 续

    20141118 最近一周做了一个关于仓库管理,拣货任务分配的模块,其中涉及到刷卡自动打印领取任务的功能点. 技术点: C#调用C++.delphi的动态链接库.动态链接库的调用方法不同.效果也不相同 ...

  4. Android Camera 3D效果

    一.概念 在Android中要想实现3D效果,第一个想到的应该就是OpenGL ES,因为在很多基础教材中几乎都提到了它.但是其使用起来还是稍微麻烦一些,而且它也主要用在游戏方面,那在应用方面有没有更 ...

  5. 【译】x86程序员手册31- 第9章 异常和中断

    Chapter 9 Exceptions and Interrupts 第9章 异常和中断 Interrupts and exceptions are special kinds of control ...

  6. [转]最值得拥有的免费Bootstrap后台管理模板

    在PHP开发项目中,后台管理因为面向群体相对比较固定,大部分以实现业务逻辑和功能.使用Bootstrap后台模板可以让后端开发很轻松的就展现给客户一个响应式的后台,节约前端开发的时间.下面PHP程序员 ...

  7. sharepoint services

    I have got solution for authentication to share point web service I have use fedAuth Cookie and rtfa ...

  8. webstom2017最新破解 ------------ http://blog.csdn.net/voke_/article/details/76418116

    webstorm 作为最近最火的前端开发工具,也确实对得起那个价格,但是秉着勤俭节约的传统美德,我们肯定是能省则省啊. 方法一:(更新时间:2018/1/23)v3.3 注册时,在打开的License ...

  9. 【Hadoop】三、HDFS命令行接口

      通过前面对HDFS基本概念.高可用性.数据读写流程的介绍,我们对HDFS已经有了大致的了解.这里我们还需要明确一点:Hadoop作为一个完整的分布式系统,它有一个抽象的文件系统的概念,而我们介绍的 ...

  10. 如何使用crash分析vmcore - 之基础思路case1

    如何使用crash分析vmcore - 之基础思路case1 dmesg查看内核日志 [2493382.671020] systemd-shutdown[1]: Sending SIGKILL to ...