史啦啦 的學(xué)生作業(yè):
【圖片】
//實現(xiàn)多個生產(chǎn)者與多個消費者模型,在示例的基礎(chǔ)上進行修改,提示,需要使用 pthread_cond_broadcast 函數(shù)喚醒所有阻塞的消費者線程
#include
#include
#include
#include
#include
#include
static int number = 0; // 共享資源
static bool producers_done = false; // 生產(chǎn)者完成標(biāo)志
static int active_producers = 0; // 活躍生產(chǎn)者計數(shù)器
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
// 生產(chǎn)者線程函數(shù)
void *producer_handler(void *arg) {
int cnt = atoi((char *)arg);
for (int i = 0; i < cnt; i++) {
pthread_mutex_lock(&mtx);
number++;
printf("Producer [%ld] created, total: %d\n",
(long)pthread_self(), number);
pthread_cond_broadcast(&cond); // 廣播喚醒所有消費者
pthread_mutex_unlock(&mtx);
usleep(1000); // 模擬生產(chǎn)耗時
}
pthread_mutex_lock(&mtx);
active_producers--;
if (active_producers == 0) {
producers_done = true;
pthread_cond_broadcast(&cond); // 最終喚醒所有消費者
}
pthread_mutex_unlock(&mtx);
return NULL;
}
// 消費者線程函數(shù)
void *consumer_handler(void *arg) {
while (1) {
pthread_mutex_lock(&mtx);
// 等待產(chǎn)品可消費或生產(chǎn)者全部完成
while (number == 0 && !producers_done) {
pthread_cond_wait(&cond, &mtx);
}
if (number > 0) {
number--;
printf("Consumer [%ld] consumed, remaining: %d\n",
(long)pthread_self(), number);
pthread_mutex_unlock(&mtx);
usleep(1500); // 模擬消費耗時
} else if (producers_done) {
pthread_mutex_unlock(&mtx);
break; // 退出條件:無產(chǎn)品且生產(chǎn)者已結(jié)束
}
}
return NULL;
}
int main(int argc, char *argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: %s ... -c \n",
argv[0]);
return EXIT_FAILURE;
}
// 解析消費者數(shù)量參數(shù)(格式:-c 3)
int consumer_count = 2; // 默認(rèn)2個消費者
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-c") == 0 && i+1 < argc) {
consumer_count = atoi(argv[i+1]);
break;
}
}
active_producers = argc - 1 - (consumer_count > 0 ? 2 : 0);
// 創(chuàng)建生產(chǎn)者線程
pthread_t producers[active_producers];
for (int i = 1, idx = 0; i < argc && idx < active_producers; i++) {
if (strcmp(argv[i], "-c") == 0) {
i++; // 跳過消費者數(shù)量參數(shù)
continue;
}
pthread_create(&producers[idx++], NULL, producer_handler, argv[i]);
}
// 創(chuàng)建消費者線程
pthread_t consumers[consumer_count];
for (int i = 0; i < consumer_count; i++) {
pthread_create(&consumers[i], NULL, consumer_handler, NULL);
}
// 等待生產(chǎn)者完成
for (int i = 0; i < active_producers; i++) {
pthread_join(producers[i], NULL);
}
// 等待消費者完成
for (int i = 0; i < consumer_count; i++) {
pthread_join(consumers[i], NULL);
}
printf("All tasks completed. Final stock: %d\n", number);
return 0;
}