生产者消费者模型

Posted Luella_G

tags:

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

1.生产者与消费者之间的关系

(1)生产者与生产者之间的关系

           互斥

(2)消费者与消费者之间的关系

           互斥

(3)生产者与消费者之间的关系

           同步与互斥

2.生产者消费者模型的描述

    有两个进程,分别称为生产者、消费者。生产者和消费者共享一段缓冲区。生产者向缓冲区中放数据,消费者从缓冲区中拿走数据。其结构如下图所示:


3.基于单链表的生产者消费者模型

当我们使用单链表模拟生产者消费者模型时,使用单链表的插入表示生产者,单链表的删除表示消费者。为了简化,插入和删除使用头插和尾插。

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

typedef struct  _node

    int _data;
    struct _node* _next;
node_t, *node_p, **node_pp;

node_p _head;

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

static node_p AllocNode(int x, node_p next)

    node_p tmp = (node_p)malloc(sizeof(node_t));
    if(!tmp)
    
        perror("malloc");
        exit(1);
    
    tmp->_data = x;
    tmp->_next = next;
    return tmp;


int IsEmpty(node_p head)

    return (head->_next == NULL)?1:0;


void FreeNode(node_p node)

    if(node != NULL)
    
        free(node);
        node = NULL;
    


void InitList(node_pp head)

    *head = AllocNode(0, NULL);


void PushHead(node_p head, int x)

    node_p tmp = AllocNode(x, NULL);
    tmp->_next = head->_next;
    head->_next = tmp;


void PopHead(node_p head, int* out)

    if(!IsEmpty(head))
    
        node_p tmp = head->_next;
        head->_next = tmp->_next;
        *out = tmp->_data;
        FreeNode(tmp);
        tmp = NULL;
    


void DestroyList(node_p head)

    int data;
    if(!IsEmpty(head))
    
        PopHead(head, &data);
    
    FreeNode(head);


void ShowList(node_p head)

    node_p start = head->_next;
    while(start)
    
        printf("%d ", start->_data);
        start = start->_next;
    


void* consume(void* arg)

    pthread_mutex_t* lockp = (pthread_mutex_t*)arg;
    int data = 0;
    while(1)
    
        pthread_mutex_lock(lockp);
        PopHead(_head, &data);
        printf("consumer done: %d ", data);
        pthread_mutex_unlock(lockp);
    


void* product(void* arg)

    pthread_mutex_t* lockp = (pthread_mutex_t*)arg;
    int data = 0;
    while(1)
    
        pthread_mutex_lock(lockp);
        data = rand() % 1234;
        PushHead(_head, data);
        printf("producter done: %d\\n", data);
        pthread_mutex_unlock(lockp);
    


int main()

    pthread_mutex_t lock;
    pthread_mutex_init(&lock, NULL);

    InitList(&_head);
    pthread_t consumer, producter;
    pthread_create(&consumer, NULL, consume, (pthread_mutex_t*)&lock);
    pthread_create(&producter, NULL, product, (pthread_mutex_t*)&lock);

    pthread_join(consumer, NULL);
    pthread_join(product, NULL);

    DestroyList(_head);
    pthread_mutex_destory(&lock);

//    int i = 0;
//    while(i < 10)
//    
//        PushHead(_head, i++);
//        sleep(1);
//        ShowList(_head);
//    
//
//    int data = 0;
//    while(i > 5)
//    
//        PopHead(_head, &data);
//        sleep(1);
//        ShowList(_head);
//        --i;
//    
//    DestroyList(_head);
	return 0;

4.基于环形队列的生产者消费者模型

环形队列的底层存储数据的方式其实就是一个数组,只要控制好对于队头和队尾的相关计算,就可以实现循环队列,而生产者依旧是在有空间的时候进行存放数据,没有空间时进入挂起等待状态,消费者则是在有数据时进行取数据,没有数据时进行挂起等待操作,这样便可以实现生产者和消费模型。

#include<stdio.h>  
#include<pthread.h>  
#include<semaphore.h>  
  
int ring[64];  
sem_t semBlank;  
sem_t semData;  
  
void* consume(void* arg)  
        int step=0;  
        while(1)  
                sem_wait(&semData);  
                int data=ring[step];  
                step++;  
                step%=64;  
                printf("consume done: %d\\n",data);  
                sem_post(&semBlank);  
          
  
  
void* product(void* arg)  
        int step=0;  
        while(1)  
        sem_wait(&semBlank);  
                int data=rand()%1234;  
                ring[step]=data;  
                step++;  
                step%=64;  
                printf("produce done: %d\\n",data);  
                sem_post(&semData);  
           
          
          
int main()  
              
        sem_init(&semBlank,0,64);  
        sem_init(&semData,0,0);  
        pthread_t consumer,producter;  
        pthread_create(&consumer,NULL,consume,NULL);   
        pthread_create(&producter,NULL,product,NULL);  
  
        pthread_join(consumer,NULL);  
        pthread_join(producter,NULL);  
          
        sem_destroy(&semBlank);  
        sem_destroy(&semData);  
        return 0;  



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

生产者消费者模型详解

生产者消费者模型详解

Linux生产者消费者模型

C++实现生产者和消费者模型

C++实现 生产者消费者模型

多线程生产者消费者模型