最简单的生产者/消费者问题

生产者/消费者问题。可以从下图中看到,有一个容器用来存放数据,我们可以把这个容器当作”交易场所“或者”仓库“,生产者只关心仓库是否存满,不需要关心消费者的情况。消费者也一样,不需要关心具体生产者的情况,具体有多少个生产者,只需要知道仓库中是否有数据,双方甚至都不知道对方的存在。
这里写图片描述
生产者消费者,是在多线程同步的一个问题,两个固定大小缓冲区的线程,在实际运行是会发生问题,生产者是生成数据放入缓冲区,重复过程,消费者在缓冲区取走数据。
总结下来就是“三、二、一原则”:
三种关系:
- 生产者之间的竞争关系
- 消费者之间的竞争关系
- 生产者和消费者之间的关系
两个角色:生产者和消费者
一个场所:有效的内存区域
比如现在可以把生产者/消费者想象成供货商以及顾客的关系。仓库就是超市。
现在我们用单链表来模拟顾客/供货商/超市。然后运用上一篇刚刚学到的互斥量和条件变量来解决这个问题。

  • 基于单链表的生产者互斥者模型
    代码:
/*************************************************************************

    > File Name: mycp.c

    > Author: 

    > Mail: 

    > Created Time: Sun 18 Jun 2017 04:55:37 AM PDT

 ************************************************************************/

#include<stdio.h>

#include<pthread.h>

#include<unistd.h>

#include<stdlib.h>

typedef struct _node{

    int data;

    struct _node* next;

}node_t,*node_p,**node_pp;

node_p head=NULL;

pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

static node_p  alloc_node(int data)

{

    node_p tmp=(node_p)malloc(sizeof(node_t));

    if(tmp==NULL)

    {

        perror("malloc");

        exit(1);

    }

    tmp->data=data;

    tmp->next=NULL;

    return tmp;

}

static void delete_node(node_p n)

{

    if(n!=NULL)

        free(n);

}

static int isEmpty(node_p h)

{

    return h->next==NULL;

}

void initList(node_pp h)

{

    *h=alloc_node(0);

}

void pushFront(node_p h,int data)

{

    node_p tmp=alloc_node(data);

    tmp->next=h->next;

    h->next=tmp;

}

void popFront(node_p h,int* out)

{

    if(!isEmpty(h))

    {

        node_p p=h->next;

        h->next=p->next;

        *out =  p->data;

        delete_node(p);

    }

}

void destoryList(node_p h)

{

    int out=0;

    while(!isEmpty(h))

    {

        popFront(h,&out);

    }

    delete_node(h);



}

void showList(node_p h)

{

    node_p start=h->next;

    while(start)

    {

        printf("%d ",start->data);

        start=start->next;

    }

    printf("\n");

}

void *product(void *arg)//生产

{

    while(1)

    {

        int data=rand()%1234;

        pthread_mutex_lock(&lock);

        pushFront(head,data);

        pthread_mutex_unlock(&lock);  

        pthread_cond_signal(&cond);

        printf("product done: %d",data);

        sleep(1);

    }

}

void *consume(void *arg)//消费

{

    int c=-1;

    while(1)

    {

        pthread_mutex_lock(&lock);

        while(isEmpty(head))

        {

            printf("consume begin waiting...\n");

            pthread_cond_wait(&cond,&lock);

        }

        popFront(head,&c);

        printf("consumer done: %d\n",c);

        pthread_mutex_unlock(&lock);

    }

}

int main()

{

    initList(&head);

    pthread_t p,c;

    pthread_create(&p,NULL,product,NULL);

    pthread_create(&c,NULL,consume,NULL);



    pthread_join(p,NULL);

    pthread_join(c,NULL);



    pthread_mutex_destroy(&lock);

    pthread_cond_destroy(&cond);



    destoryList(head);

    return 0;

}

生产者生产节点,消费者消费节点,如果现在链表中没有节点则等待。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值