一、生产消费模型:我们可以用条件变量来实现线程之间的同步,利用一个生产消费模型具体的实现同步。生产消费模型可以简单地称为3,2,1模型(即3种关系,2个对象,1个场所),同时还需注意以下3点:

1、生产者和消费者是同步互斥关系;

2、生产者和生产者是互斥关系;

3、消费者和消费者是互斥关系。

二、条件变量的理解:线程A需要等某个条件成才能继续往下执,现在这个条件不成,线程A就阻塞等待,线程B在执过程中使这个条件成了,就唤醒线程A继续执。 在pthread库中通过条件变量(Condition Variable)来阻塞等待个条件,或者唤醒等待这个条件的线程。

相关函数有:

wKiom1ccgqyS1HiyAAA4w3a3u04581.png


1、初始化:thread_cond_init函数初始化个Condition Variable,attr参数 为NULL则表缺省属性,pthread_cond_destroy函数销毁个Condition Variable。如果ConditionVariable是静态分配的,也可以宏定义PTHEAD_COND_INITIALIZER初始化,相当于pthread_cond_init函数初始化并且attr参数为NULL。

wKioL1ccg46zT2JRAAA5ukukx9E853.png

2、阻塞等待线程:个线程可以调 pthread_cond_wait在个Condition Variable上阻塞等待,这个函数做以下三步操作:
1). 释放Mutex
2). 阻塞等待
3). 当被唤醒时,重新获得Mutex并返回

个线程可以调pthread_cond_signal唤醒在某个Condition Variable上等待的另个线程,也可以调pthread_cond_broadcast唤醒在这个Condition Variable上等待的所有线程。


代码实现:

创建生产者使用的是链表,整个过程是生产者从链表表尾生产数据,消费者从表头获取数据。并且是多生产者多消费者模型。

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

typedef struct list
{
    int _data;
    struct list* _next;
}product_list;

product_list* head=NULL;

static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t need_product=PTHREAD_COND_INITIALIZER;

product_list* createNode(int data)
{
    product_list* tmp=malloc(sizeof(product_list));
    tmp->_data=data;
    tmp->_next=NULL;
    return tmp;
}

void InitList(product_list** phead)
{
    *phead=createNode(0);
}

int Push(product_list* phead,int data)
{
    product_list* tail=phead;
    while(tail->_next!=NULL)
    {
        tail=tail->_next;
    }
    product_list* new=createNode(data);
    tail->_next=new;
    return new->_data;
}

int Pop(product_list* phead)
{
    product_list* tmp=phead->_next;
    phead->_next=phead->_next->_next;
    phead=phead->_next;
    tmp->_next=NULL;
    int val=tmp->_data;
    free(tmp);
    tmp=NULL;
        return val;
}

void* product(void* arg)
{
    int i=0;
    for(;i<10;i++)
    {
        sleep(3);
        pthread_mutex_lock(&lock);
        int val=Push(head,i);
        pthread_mutex_unlock(&lock);
        printf("product success!the data is:%d\n",val);
        pthread_cond_signal(&need_product);
    }
}

void* consumer(void* arg)
{
    while(1)
    {
        pthread_mutex_lock(&lock);
        while(head->_next==NULL)
        {
            pthread_cond_wait(&need_product,&lock);
        }
        int val=Pop(head);
        pthread_mutex_unlock(&lock);
        printf("consumer data is:%d\n",val);
    }
    return NULL;
}

int main()
{
    InitList(&head);
    pthread_t product1;
    pthread_t product2;
    pthread_t product3;
    
    pthread_t consumer1;
    pthread_t consumer2;
    pthread_t consumer3;

    pthread_create(&product1,NULL,product,NULL);
    pthread_create(&product2,NULL,product,NULL);
    pthread_create(&product3,NULL,product,NULL);

    pthread_create(&consumer1,NULL,consumer,NULL);
    pthread_create(&consumer2,NULL,consumer,NULL);
    pthread_create(&consumer3,NULL,consumer,NULL);

    pthread_join(product1,NULL);
    pthread_join(product2,NULL);
    pthread_join(product3,NULL);

    pthread_join(consumer1,NULL);
    pthread_join(consumer2,NULL);
    pthread_join(consumer3,NULL);

    return 0;
}

运行结果如下:

wKioL1cchOrjOHs3AABQLlVMbbU883.png