生产者消费者模型

生产者消费者模型可以被称为“三二一原则”
“三”是指有三个原则,这三个原则分别是:
(1)生产者与生产者之间是互斥的关系。
(2)生产者与消费者之间是同步与互斥关系。
(3)消费者与消费者是互斥的关系。
“二”是指两种角色:生产者和消费者
“一”是指一个交易场所
基于单链表实现的生产者与消费者模型:

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

typedef struct Listnode{
    int data;
    struct Listnode *next;
}node,*pnode,**ppnode;

pnode head = NULL;
pthread_mutex_t lock =PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t cond =PTHREAD_COND_INITIALIZER; 

static pnode AllocListnode(int data)
{
    pnode tmp = (pnode)malloc(sizeof(node));
    if(tmp ==NULL)
    {
        perror("malloc");
        exit(1);
    }
    tmp->data = data;
    tmp->next = NULL;
}

static void DeleteListnode(pnode n)
{
    if(n){
        free(n);
    }
}

void InitList(ppnode node)
{
    *node = AllocListnode(0);
}

void PushFront(pnode node,int data)
{
    pnode tmp = AllocListnode(data);
    tmp->next = node->next;
    node->next = tmp;
}

void PopFront(pnode node,int *out)
{
    if(!Empty(node))
    {
    pnode tmp = node->next;
    node->next = tmp->next;
    *out = tmp->data;
    DeleteListnode(tmp);
    }
}

void ShowList(pnode node)
{
    pnode start = node->next;
    while(start)
    {
        printf("%d",start->data);
        start = start->next;
    }
    printf("\n");
}

void Destory(pnode node)
{
    int tmp = 0;
    while(!Empty(node))
    {
        PopFront(node,&tmp);
    }
    DeleteListnode(node);
}

int  Empty(pnode node)
{
    return node->next ==NULL? 1:0;
}

//消费者
 void *Consum(void *arg)
 {
     int c;
     while(1)
     {
         c = -1;
         //加锁
         pthread_mutex_lock(&lock);
         //如果为空等待
         while(Empty(head))
         {
             printf("consum begin waiting...\n");
             //条件变量等待
             pthread_cond_wait(&cond,&lock);
         }
         PopFront(head,&c);
         pthread_mutex_unlock(&lock);
         printf("consum done: %d \n",c);
        // sleep(3);
     }
 }

 //生产者
 void *Product(void *arg)
 {
     int p;
     while(1)
     {
         p = rand()%1234;
         pthread_mutex_lock(&lock);
         PushFront(head,p);
         pthread_mutex_unlock(&lock);
         //生产完了给消费者信号
         pthread_cond_signal(&cond);
         printf("product done: %d\n",p);
         sleep(3);
     }
 }

 int main()
 {
     //初始化链表
     InitList(&head);
     //创建生产者和消费者线程
     pthread_t P,C;
     pthread_create(&P,NULL,Product,NULL);
     pthread_create(&C,NULL,Consum,NULL);

     pthread_join(C,NULL);
     pthread_join(P,NULL);

     pthread_mutex_destroy(&lock);
     pthread_cond_destroy(&cond);

     //销毁链表
     Destory(head);
     return 0;
 }

基于环形队列的生产者消费者模型
必须满足 的条件
消费者必须紧跟在生产者的后面(不能超过)
生产者不能给 消费者套圈
生产者和消费者不能在同一个格子
如果为满 : 消费者先跑
如果为空: 生产者先跑
基于环形队列的生产者与消费者模型:

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

#define SIZE  64
int ring[SIZE];
sem_t blank_sem;
sem_t data_sem;

pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;

void *Product1(void *arg)
{
    int step = 0;
    int data = 0;
    while(1)
    {
     pthread_mutex_lock(&lock1);
     sem_wait(&blank_sem);
     ring[step++] = data;
     sem_post(&data_sem);
     pthread_mutex_unlock(&lock1);
     step %= SIZE;
     printf("Product1 done: %d\n",data++);
     sleep(3); 
    }
}

void *Product2(void *arg)
{
    int step = 0;
    int data = 0;
    while(1)
    {
     pthread_mutex_lock(&lock1);
     sem_wait(&blank_sem);
     ring[step++] = data;
     sem_post(&data_sem);
     pthread_mutex_unlock(&lock1);
     step %= SIZE;
     printf("Product2  done: %d\n",data++);
     sleep(3);
    }
}


void *Comsum1(void *arg)
{
    int step = 0;
    while(1)
    {
        sleep(1);
        pthread_mutex_lock(&lock2);
        sem_wait(&data_sem);
        int data = ring[step++];
        sem_post(&blank_sem);
        pthread_mutex_unlock(&lock2);
        //环形
        step %= SIZE;
    printf("Comsum1 done :%d\n",data);

    }
}

void *Comsum2(void *arg)
{
    int step = 0;
    while(1)
    {
        sleep(1);
        pthread_mutex_lock(&lock2);
        sem_wait(&data_sem);
        int data = ring[step++];
        sem_post(&blank_sem);
        pthread_mutex_unlock(&lock2);
        //环形
        step %= SIZE;
    printf("Comsum2 done :%d\n",data);
    }
}

int main()
{
    sem_init(&blank_sem,0,SIZE);
    sem_init(&data_sem,0,0);

    pthread_t P1,P2, C1,C2;
    pthread_create(&P1,NULL,Product1,NULL);
    pthread_create(&P2,NULL,Product2,NULL);
    pthread_create(&C1,NULL,Comsum1,NULL);
    pthread_create(&C2,NULL,Comsum2,NULL);

    pthread_join(P1,NULL);
    pthread_join(P2,NULL);
    pthread_join(C1,NULL);
    pthread_join(C2,NULL);

    sem_destroy(&blank_sem);
    sem_destroy(&data_sem);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值