生产者-消费者模型

Posted si-lei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生产者-消费者模型相关的知识,希望对你有一定的参考价值。

1. 条件变量+互斥锁 实现 生产者-消费者模型:

技术分享图片

/*借助条件变量模拟 生产者-消费者 问题*/
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>

/*链表作为公享数据,需被互斥量保护*/    //模拟箩筐
struct msg {
    struct msg *next;
    int num;
};

struct msg *head;
struct msg *mp;

/* 静态初始化 一个条件变量 和 一个互斥量*/
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;    //条件变量静态初始化
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;        //互斥锁静态初始化

void *consumer(void *p)//消费者
{
    for (;;) {
        pthread_mutex_lock(&lock);//加锁
        while (head == NULL) {           //头指针为空,说明没有节点    可以为if吗
            pthread_cond_wait(&has_product, &lock);
        }
        mp = head;      
        head = mp->next;    //模拟消费掉一个产品
        pthread_mutex_unlock(&lock);//解锁

        printf("-Consume ---%d
", mp->num);
        free(mp);
        mp = NULL;
        sleep(rand() % 5);
    }
}

void *producer(void *p)//生产者
{
    for (;;) {
        mp = malloc(sizeof(struct msg));
        mp->num = rand() % 1000 + 1;        //模拟生产一个产品
        printf("-Produce ---%d
", mp->num);

        pthread_mutex_lock(&lock);//加锁
        mp->next = head;//头插法
        head = mp;
        pthread_mutex_unlock(&lock);//解锁

        pthread_cond_signal(&has_product);  //将等待在该条件变量上的一个线程唤醒
        sleep(rand() % 5);
    }
}

int main(int argc, char *argv[])
{
    pthread_t pid, cid;
    srand(time(NULL));

    pthread_create(&pid, NULL, producer, NULL);//创建生产者线程
    pthread_create(&cid, NULL, consumer, NULL);//创建消费者线程

    pthread_join(pid, NULL);//回收线程
    pthread_join(cid, NULL);

    return 0;
}

 

2. 信号量 实现 生产者-消费者模型:

 技术分享图片

/*信号量实现 生产者 消费者问题*/

#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>

#define NUM 5               

int queue[NUM];                                     //全局数组实现环形队列
sem_t blank_number, product_number;                 //空格子信号量, 产品信号量

void *producer(void *arg)
{
    int i = 0;

    while (1) {
        sem_wait(&blank_number);                    //生产者将空格子数--,为0则阻塞等待
        queue[i] = rand() % 1000 + 1;               //生产一个产品,存入队列
        printf("----Produce---%d
", queue[i]);        
        sem_post(&product_number);                  //将产品数++

        i = (i+1) % NUM;                            //借助下标实现环形,下标往后移
        sleep(rand()%3);
    }
}

void *consumer(void *arg)
{
    int i = 0;

    while (1) {
        sem_wait(&product_number);                  //消费者将产品数--,为0则阻塞等待
        printf("-Consume---%d
", queue[i]);
        queue[i] = 0;                               //消费一个产品 
        sem_post(&blank_number);                    //消费掉以后,将空格子数++

        i = (i+1) % NUM;
        sleep(rand()%3);
    }
}

int main(int argc, char *argv[])
{
    pthread_t pid, cid;

    sem_init(&blank_number, 0, NUM);                //初始化空格子信号量为5
    sem_init(&product_number, 0, 0);                //产品数为0

    pthread_create(&pid, NULL, producer, NULL);    //创建生产者线程
    pthread_create(&cid, NULL, consumer, NULL);    //创建消费者线程

    pthread_join(pid, NULL);    //回收线程
    pthread_join(cid, NULL);

    sem_destroy(&blank_number);    //销毁信号量
    sem_destroy(&product_number);

    return 0;
}

 

以上是关于生产者-消费者模型的主要内容,如果未能解决你的问题,请参考以下文章

golang生产者消费者模型示例代码

LINUX多线程(生产者消费者模型,POXIS信号量)

转: Java并发编程之十三:生产者—消费者模型(含代码)

Java生产消费者模型——代码解析

生产者消费者模型

生产者消费者模型-Java代码实现