問題描述
一組生產者線程和一組消費者線程共享一個初始爲空、大小爲n的緩衝區,只有緩衝區沒滿時,生產者才能把消息放入到緩衝區,否則必須等待;只有緩衝區不空時,消費者才能從中取出消息,否則必須等待。由於緩衝區是臨界資源,它只允許一個生產者放入消息,或者一個消費者從中取出消息。
問題分析
-
關係分析。生產者和消費者對緩衝區互斥訪問是互斥關係,同時生產者和消費者又是一個相互協作的關係,只有生產者生產之後,消費者才能消費,他們也是同步關係。
-
整理思路。這裏比較簡單,只有生產者和消費者兩種線程,正好是多個線程存在着互斥關係和同步關係。那麼需要解決的是互斥和同步PV操作的位置。
-
模擬問題。使用隊列模擬緩衝區,生產者與消費者用獨立線程模擬。
-
實現同步。鎖mutex,用於控制互斥訪問緩衝池以及與條件變量配合使用;條件變量cond用於消費者記錄當前緩衝池中是否非空。條件變量cond1用於生產者記錄當前緩衝池中是否已滿。
核心代碼
void *producer(void *a)
{
while(1){
pthread_mutex_lock(&mutex);
while(full(&pc)==1){
printf("生產者%ld等待中\n",pthread_self());
pthread_cond_wait(&cond,&mutex);
}
produce(&pc);
printf("生產者%ld生產%d\n",pthread_self(),pc.tail->date);
if(pc.len==1){
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void *consumer(void *a)
{
while(1){
pthread_mutex_lock(&mutex);
while(empty(&pc)==1){
printf("\t\t\t消費者%ld等待中\n",pthread_self());
pthread_cond_wait(&cond,&mutex);
}
printf("\t\t\t消費者%ld消費%d\n",pthread_self(),pc.head->date);
consume(&pc);
if(pc.len==5){
pthread_cond_signal(&cond1);
}
pthread_mutex_unlock(&mutex);
sleep(1);
}
}