線程的生產者消費者模型

1. 基於單鏈表的生產者與消費者模型

  1. 生產者—消費者模型的321原則:
    3種關係:

        生產者-生產者 ***互斥***
        消費者-消費者 ***互斥***
        生產者-消費者 ***互斥,同步***
    

    2種角色:

    消費者 生產者
    

    1個交易場所:

    臨界資源
    
  2. 實現321的方法:

1個交易場所:創建一個帶頭節點的鏈表:

typedef struct _head //結構體聲明
{
    int data;
    struct _head *next;
}Node,*Node_p,**Node_pp;

Node_p head; //頭指針聲明

void InitList(Node_pp _h) //初始化帶頭節點鏈表
{
    *_h =(Node_p)malloc(sizeof(Node));
    (*_h)->next = NULL;
}
void PushFrond(Node_p _h,int K)//
{
    Node_p tmp = _h->next;
    _h->next =(Node_p)malloc(sizeof(Node));
    _h = _h->next;
    _h->data = K;
    _h->next = tmp;
}

Node_p PopFrond(Node_p _h)
{
    if(_h->next == NULL)
        return NULL;
    Node_p tail = _h->next;
    _h->next = tail->next;
    return tail;
}

兩個角色:我們需要創建兩個線程:

void *consume(void *arg) // 用於消費,即調用PopFrond
void &product(void *arg) //用於生產,即調用PushFrond

互斥:函數consume與product不能運行臨界區,即消費者,生產者不能同時訪問臨界資源(不能同時改變鏈表head):
我們可以用互斥鎖

pthread_mutex_t mutex_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mutex_lock);//加鎖
pthread_mutex_unlock(&mutex_lock);//解鎖

同步:消費者不能超過生產者消費,當消費者發現沒有資源時,就掛起等待,當生產者放入資源後發送信號喚醒消費者消費;
可以用條件變量即同時滿足同步:

pthread_cond_t  cond = PTHREAD_COND_INITIALIZER; 
pthread_cond_wait(&cond,&mutex_lock);//等待
pthread_cond_signal(&cond);//發信號
信號的功能:
1.釋放鎖 //讓其他線程訪問臨界區
2. 阻塞等待/
3. 喚醒時重新獲得鎖

消費者-生產者模型編寫:

void* product(void *arg)
{
    while(1){
        int n = rand()/12123;
        pthread_mutex_lock(&mutex_lock);    //解鎖訪問
        PushFrond(head,n);
        printf("product done! %d\n",n);
        pthread_mutex_unlock(&mutex_lock);//解鎖
        pthread_cond_signal(&cond);//生產完成,發送信號,消費者消費
        sleep(2);
    }
    return NULL;
}

void *consum(void *arg)
{
    while(1){
        pthread_mutex_lock(&mutex_lock);//加鎖訪問
        Node_p tmp = PopFrond(head);
        while(tmp == NULL)//當沒有資源時,則阻塞等待
        {
            pthread_cond_wait(&cond, &mutex_lock);
            tmp = PopFrond(head);
        }
        printf("consum done! %d\n",tmp->data);
        pthread_mutex_unlock(&mutex_lock);//解鎖
    }
    return NULL;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章