枝wenz_fpJNR0 的学生作业:
#include
#include
#include
#include
#include
static int number = 0; // 共享变量(产品数量)
static int total_produced = 0; // 总生产数量
static int total_consumed = 0; // 总消费数量
static int producer_count = 0; // 生产者线程数量
static int producers_finished = 0; // 已完成的生产者数量
static bool all_producers_done = false;
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond_producer = PTHREAD_COND_INITIALIZER; // 生产者条件变量
static pthread_cond_t cond_consumer = PTHREAD_COND_INITIALIZER; // 消费者条件变量
// 生产者线程函数
void *producer_handler(void *arg)
{
int cnt = atoi((char *)arg);
int i;
for(i = 0; i < cnt; i++){
pthread_mutex_lock(&mtx);
// 可选:如果缓冲区满了,生产者等待(这里假设无限缓冲区)
number++;
total_produced++;
printf("生产者线程 [%ld] 生产一个产品,当前产品数量为:%d,总生产量:%d\n",
pthread_self(), number, total_produced);
pthread_mutex_unlock(&mtx);
// 唤醒所有等待的消费者
pthread_cond_broadcast(&cond_consumer);
// 模拟生产时间
usleep(100000);
}
// 生产者完成工作
pthread_mutex_lock(&mtx);
producers_finished++;
printf("生产者线程 [%ld] 已完成生产任务,剩余生产者:%d\n",
pthread_self(), producer_count - producers_finished);
if(producers_finished >= producer_count){
all_producers_done = true;
// 所有生产者完成,广播唤醒所有消费者以便它们退出
pthread_cond_broadcast(&cond_consumer);
}
pthread_mutex_unlock(&mtx);
pthread_exit((void *)0);
}
// 消费者线程函数
void *consumer_handler(void *arg)
{
int consumer_id = *(int *)arg;
while(1){
pthread_mutex_lock(&mtx);
// 当没有产品且生产者还没全部完成时,等待
while(number == 0 && !all_producers_done){
printf("消费者线程 [%ld] (ID:%d) 等待产品...\n", pthread_self(), consumer_id);
pthread_cond_wait(&cond_consumer, &mtx);
}
// 如果没有产品且所有生产者已完成,退出
if(number == 0 && all_producers_done){
pthread_mutex_unlock(&mtx);
break;
}
// 消费一个产品
if(number > 0){
number--;
total_consumed++;
printf("消费者线程 [%ld] (ID:%d) 消费一个产品,剩余产品数量:%d,总消费量:%d\n",
pthread_self(), consumer_id, number, total_consumed);
pthread_mutex_unlock(&mtx);
// 可选:唤醒生产者(如果需要限制缓冲区大小)
// pthread_cond_signal(&cond_producer);
// 模拟消费时间
usleep(150000);
} else {
pthread_mutex_unlock(&mtx);
}
}
printf("消费者线程 [%ld] (ID:%d) 退出\n", pthread_self(), consumer_id);
pthread_exit((void *)0);
}
int main(int argc, char *argv[])
{
pthread_t *producer_tids, *consumer_tids;
int i;
int err;
int consumer_num = 3; // 消费者线程数量
int *consumer_ids;
// 至少需要提供一个生产者参数
if(argc < 2){
printf("用法: %s [生产数量2] ...\n", argv[0]);
printf("示例: %s 5 3 2 (创建3个生产者,分别生产5,3,2个产品)\n", argv[0]);
return 1;
}
producer_count = argc - 1;
// 分配线程ID数组
producer_tids = (pthread_t *)malloc(producer_count * sizeof(pthread_t));
consumer_tids = (pthread_t *)malloc(consumer_num * sizeof(pthread_t));
consumer_ids = (int *)malloc(consumer_num * sizeof(int));
if(!producer_tids || !consumer_tids || !consumer_ids){
perror("malloc failed");
exit(EXIT_FAILURE);
}
printf("创建 %d 个生产者线程, %d 个消费者线程\n", producer_count, consumer_num);
// 创建生产者线程
for(i = 0; i < producer_count; i++){
err = pthread_create(&producer_tids[i], NULL, producer_handler, (void *)argv[i+1]);
if(err != 0){
perror("[ERROR] pthread_create() for producer: ");
exit(EXIT_FAILURE);
}
printf("创建生产者线程 [%ld]\n", producer_tids[i]);
}
// 创建消费者线程
for(i = 0; i < consumer_num; i++){
consumer_ids[i] = i;
err = pthread_create(&consumer_tids[i], NULL, consumer_handler, (void *)&consumer_ids[i]);
if(err != 0){
perror("[ERROR] pthread_create() for consumer: ");
exit(EXIT_FAILURE);
}
printf("创建消费者线程 [%ld] ID=%d\n", consumer_tids[i], i);
}
// 等待所有生产者线程结束
for(i = 0; i < producer_count; i++){
pthread_join(producer_tids[i], NULL);
}
printf("\n所有生产者线程已完成\n");
// 等待所有消费者线程结束
for(i = 0; i < consumer_num; i++){
pthread_join(consumer_tids[i], NULL);
}
printf("\n=== 最终统计 ===\n");
printf("总生产数量: %d\n", total_produced);
printf("总消费数量: %d\n", total_consumed);
printf("剩余产品数量: %d\n", number);
// 清理资源
free(producer_tids);
free(consumer_tids);
free(consumer_ids);
// 销毁互斥锁和条件变量
pthread_mutex_destroy(&mtx);
pthread_cond_destroy(&cond_producer);
pthread_cond_destroy(&cond_consumer);
return 0;
}