生产者消费者模型

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;  
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值