#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. C语言用指针输出数组里的值

    因为*(arr)是指arr数组内存编号所对应的首地址的值,即arr[0]的值.所以用*(arr+i)可以实现遍历整个数组.

  2. MyBatis 之一 简介

    什么是 MyBatis ? MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...

  3. magento 购物车 首页 显示

    如何将购物车显示在你的首页 1.复制代码:<!--new block -->                <block type="checkout/cart_sideb ...

  4. Protecting resources in iPhone and iPad apps

    源码:https://github.com/lingzhao/EncryptedResourceDemo UPDATE: The example project has been updated to ...

  5. JMeter怎样测试WebSocket,如何设置(一)

    一.安装WebSocket取样器 1.从JMeter插件管理器官网下载:https://jmeter-plugins.org/ 把这6个jar包放到C:\JMeter\apache-jmeter-3. ...

  6. nfs服务权限配置

    nfs服务权限配置 1. 查看系统是否已经安装了服务Rpm -qa | grep nfs 2. 启动服务,并且开机自动运行Systemctl start nfsSystemctl enabled nf ...

  7. A2. JVM 类加载机制

    [概述] 虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是虚拟机的类加载机制. 与那些在编译时需要进行连接 ...

  8. Android开发技巧一--weight属性实现视图的居中(半)显示

    面试时,一位面试官问到:“如果我想讲按钮居中显示,并且占据其父视图宽度的一半,应该怎么做到呢?”即实现这种效果: 我们使用weightSum属性和layout_weight属性实现这一要求: < ...

  9. C++中重载,重写,隐藏的区别

    重载: 重载是指在同一个作用域下,函数的函数名相同,但是函数参数的个数,或者参数的类型,参数的顺序不同.这时函数之间就构成了重载关系,这里需要注意的是,如果函数的参数列表完全相同,仅仅是返回值类型不同 ...

  10. Luogu P1349 广义斐波那契数列

    解题思路 既然广义斐波那契,而且数据范围这么大,那么我们使用矩阵快速幂来进行求解.大家都知道斐波那契的初始矩阵如下 $$\begin{bmatrix}1&1\\1&0\end{bmat ...