生產者消費者問題
這是一個非常經典的多線程題目,題目大意如下:有一個生產者在生產產品,這些產品將提供給若干個消費者去消費,為了使生產者和消費者能並發執行,在兩者之間設置一個有多個緩沖區的緩沖池,生產者將它生產的產品放入一個緩沖區中,消費者可以從緩沖區中取走產品進行消費,所有生產者和消費者都是異步方式運行的,但它們必須保持同步,即不允許消費者到一個空的緩沖區中取產品,也不允許生產者向一個已經裝滿產品且尚未被取走的緩沖區中投放產品。
程序:
- // producer_consumer.cpp
- //////////////////////////////////////////////////////////////////////
- // 有一個生產者在生產產品,這些產品將提供給若干個消費者去消費,為了使生產者和消費者能並發執行,
- // 在兩者之間設置一個有多個緩沖區的緩沖池,生產者將它生產的產品放入一個緩沖區中,消費者可以從緩
- // 沖區中取走產品進行消費,所有生產者和消費者都是異步方式運行的,但它們必須保持同步,即不允許消
- // 費者到一個空的緩沖區中取產品,也不允許生產者向一個已經裝滿產品且尚未被取走的緩沖區中投放產品。
- //////////////////////////////////////////////////////////////////////
-
- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
-
-
- const int BUFFER_LENGTH = 100;
- int buffer[BUFFER_LENGTH];
- int front = 0, rear = -1; // 緩沖區的前端和尾端
- int size = 0;
-
- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t empty_cond = PTHREAD_COND_INITIALIZER;
- pthread_cond_t full_cond = PTHREAD_COND_INITIALIZER;
-
- bool producer_wait = false;
- bool consumer_wait = false;
-
- void *producer(void *arg);
- void *consumer(void *arg);
-
- int main(int argc, char **argv)
- {
- pthread_t producer_id;
- pthread_t consumer_id;
-
- pthread_create(&producer_id, NULL, producer, NULL);
-
- pthread_create(&consumer_id, NULL, consumer, NULL);
-
- sleep(1);
-
- return 0;
- }
-
- void *producer(void *arg)
- {
- pthread_detach(pthread_self());
-
- while (true)
- {
- pthread_mutex_lock(&mutex);
- if (size == BUFFER_LENGTH) // 如果緩沖區已滿,等待; 否則,添加新產品
- {
- printf("buffer is full. producer is waiting...\n");
- producer_wait = true;
- pthread_cond_wait(&full_cond, &mutex);
- producer_wait = false;
- }
- // 往尾端添加一個產品
- rear = (rear + 1) % BUFFER_LENGTH;
- buffer[rear] = rand() % BUFFER_LENGTH;
- printf("producer produces the item %d: %d\n", rear, buffer[rear]);
- ++size;
- if (size == 1) // 如果當前size=1, 說明以前size=0, 消費者在等待,則給消費者發信號
- {
- while (true)
- {
- if (consumer_wait)
- {
- pthread_cond_signal(&empty_cond);
- break;
- }
- }
- }
- pthread_mutex_unlock(&mutex);
- }
- }
-
- void *consumer(void *arg)
- {
- pthread_detach(pthread_self());
-
- while (true)
- {
- pthread_mutex_lock(&mutex);
- if (size == 0) // 如果緩沖區已空,等待; 否則,消費產品
- {
- printf("buffer is empty. consumer is waiting...\n");
- consumer_wait = true;
- pthread_cond_wait(&empty_cond, &mutex);
- consumer_wait = false;
- }
- // 從前端消費一個產品
- printf("consumer consumes an item%d: %d\n", front, buffer[front]);
- front = (front + 1) % BUFFER_LENGTH;
- --size;
- if (size == BUFFER_LENGTH-1) // 如果當前size=BUFFER_LENGTH-1,www.linuxidc.com說明以前生產者在等待,則給生產者發信號
- {
- while (true)
- {
- if (producer_wait)
- {
- pthread_cond_signal(&full_cond);
- break;
- }
- }
- }
- pthread_mutex_unlock(&mutex);
- }
- }