C语言多线程读写交替执行问题求助(附出错代码)
问题描述
我想编写一个包含reader和writer两个线程的程序,两个线程各运行10次迭代,需要通过同步机制实现二者交替执行。仅使用mutex无法实现需求,改用条件变量后程序陷入无限等待状态,以下是我尝试的代码:
int my_global = 0; int write_flag = 0; pthread_mutex_t mutex; pthread_cond_t mycond; void *reader() { for(int j=0;j<10;j++){ pthread_mutex_lock(&mutex); printf("\nReader - value of global is %d & write flag is %d and j is %d",my_global,write_flag,j); write_flag = 1; pthread_mutex_unlock(&mutex); pthread_cond_signal(&mycond); // sleep(1); } } void *writer(){ for(int k=0;k<10;k++){ pthread_mutex_lock(&mutex); printf("\nstarted writer"); while(write_flag!=1){ pthread_cond_wait(&mycond,&mutex); } write_flag = 0; my_global++; printf("\nwriter done and writeflag is %d and global is %d and k is %d",write_flag,my_global,k); pthread_mutex_unlock(&mutex); } } int main() { pthread_t my_reader; pthread_t my_writer; pthread_cond_init(&mycond,NULL); pthread_mutex_init(&mutex,NULL); if (pthread_create(&my_reader, NULL, &reader, NULL) != 0) { perror("Failed to create thread"); } if (pthread_create(&my_writer, NULL, &writer, NULL) != 0) { perror("Failed to create thread"); } if (pthread_join(my_reader, NULL) != 0) { perror("Failed to join thread"); } if (pthread_join(my_writer, NULL) != 0) { perror("Failed to join thread"); } pthread_mutex_destroy(&mutex); pthread_cond_destroy(&mycond); return 0; }
问题分析
你的代码存在几个关键问题导致无限等待:
- 信号丢失:reader线程解锁后才发送条件变量信号,如果此时writer线程还未进入
pthread_cond_wait,信号会直接丢失,后续writer进入等待后无法被唤醒。 - 单向通知:只有reader通知writer执行,writer完成后没有通知reader启动下一次迭代,导致reader跑完10次后writer可能还未完成全部迭代,或者出现执行顺序混乱。
- 状态逻辑模糊:
write_flag仅标记writer是否可以执行,但没有标记reader的执行权限,无法形成双向交替的同步逻辑。
修正后的代码
#include <stdio.h> #include <pthread.h> int my_global = 0; // 0: 等待reader执行,1: 等待writer执行 int turn = 0; pthread_mutex_t mutex; pthread_cond_t cond; void *reader() { for(int j=0;j<10;j++){ pthread_mutex_lock(&mutex); // 循环检查状态,防止虚假唤醒 while(turn != 0) { pthread_cond_wait(&cond, &mutex); } printf("\nReader - global value: %d, turn: %d, iteration: %d", my_global, turn, j); // 切换状态,让writer可以执行 turn = 1; // 持有锁时发送信号,确保writer能接收到 pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); } return NULL; } void *writer(){ for(int k=0;k<10;k++){ pthread_mutex_lock(&mutex); while(turn != 1) { pthread_cond_wait(&cond, &mutex); } my_global++; printf("\nWriter done - turn: %d, global value: %d, iteration: %d", turn, my_global, k); // 切换状态,让reader可以执行 turn = 0; pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); } return NULL; } int main() { pthread_t my_reader; pthread_t my_writer; pthread_cond_init(&cond, NULL); pthread_mutex_init(&mutex, NULL); if (pthread_create(&my_reader, NULL, &reader, NULL) != 0) { perror("Failed to create reader thread"); } if (pthread_create(&my_writer, NULL, &writer, NULL) != 0) { perror("Failed to create writer thread"); } if (pthread_join(my_reader, NULL) != 0) { perror("Failed to join reader thread"); } if (pthread_join(my_writer, NULL) != 0) { perror("Failed to join writer thread"); } pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); return 0; }
关键修改说明
- 明确状态变量:用
turn变量清晰标记当前该哪个线程执行,避免原逻辑中状态模糊的问题。 - 双向通知机制:每个线程执行完任务后,切换状态并通知对方线程,形成交替执行的闭环。
- 规范条件变量使用:在持有锁的情况下发送信号,避免信号丢失;用
while循环检查状态,处理条件变量的虚假唤醒问题。 - 优化输出逻辑:移除writer线程中提前打印的"started writer",确保只有轮到自己执行时才输出操作信息,符合交替执行的预期。
内容的提问来源于stack exchange,提问作者Mughunth Srinivasan
相关产品推荐
相关产品推荐

