線程同步之——條件變量(生產消費模型)

1、生產消費模型:咱們能夠用條件變量來實現線程之間的同步,利用一個生產消費模型具體的實現同步。生產消費模型能夠簡單地稱爲3,2,1模型(即3種關係,2個對象,1個場所),同時還需注意如下3點:ide

一、生產者和消費者是同步互斥關係;函數

二、生產者和生產者是互斥關係;spa

三、消費者和消費者是互斥關係。線程

2、條件變量的理解:線程A須要等某個條件成才能繼續往下執,如今這個條件不成,線程A就阻塞等待,線程B在執過程當中使這個條件成了,就喚醒線程A繼續執。 在pthread庫中經過條件變量(Condition Variable)來阻塞等待個條件,或者喚醒等待這個條件的線程。
3d

相關函數有:對象

wKiom1ccgqyS1HiyAAA4w3a3u04581.png


一、初始化:thread_cond_init函數初始化個Condition Variable,attr參數 爲NULL則表缺省屬性,pthread_cond_destroy函數銷燬個Condition Variable。若是ConditionVariable是靜態分配的,也能夠宏定義PTHEAD_COND_INITIALIZER初始化,至關於pthread_cond_init函數初始化而且attr參數爲NULL。
blog

wKioL1ccg46zT2JRAAA5ukukx9E853.png

二、阻塞等待線程:個線程能夠調 pthread_cond_wait在個Condition Variable上阻塞等待,這個函數作如下三步操做:
1). 釋放Mutex
2). 阻塞等待
3). 當被喚醒時,從新得到Mutex並返回
get

個線程能夠調pthread_cond_signal喚醒在某個Condition Variable上等待的另個線程,也能夠調pthread_cond_broadcast喚醒在這個Condition Variable上等待的全部線程。同步


代碼實現:it

建立生產者使用的是鏈表,整個過程是生產者從鏈表表尾生產數據,消費者從表頭獲取數據。而且是多生產者多消費者模型。

#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

相關文章
相關標籤/搜索