使用C与Posix线程实现严格交替忙等待方案的问题排查
问题排查与修复
第一个问题:主线程提前终止
你写的main函数创建完线程就直接return 0了,这会让整个进程立刻结束,所有子线程都会被强制杀死。这就是为啥输出不稳定甚至完全没内容的主要原因——线程可能刚启动,还没来得及打印内容就被干掉了。
第二个问题:共享变量的可见性
turn和count是多线程共用的全局变量,但没加volatile修饰。编译器可能会把这些变量缓存到线程的寄存器里,导致线程看不到其他线程对变量的修改,轻则逻辑出错,重则死循环。
修复后的完整代码
#include <pthread.h> #include <stdio.h> #include <unistd.h> // 加volatile保证多线程下变量修改能被及时看到 volatile int count = 0; volatile int turn = 1; struct arg_struct { int my_id; int other; }; void *runner(void *param) { struct arg_struct *args = (struct arg_struct *)param; int my_id = args->my_id; int other = args->other; printf("my_id %d\n", my_id); printf("other %d\n", other); printf("Running p_thread %d\n", my_id); fflush(stdout); // 强制刷新输出,避免缓冲导致没显示 while(1) { // 等待自己的回合 while (turn != my_id) { } // 临界区操作 count += my_id; printf("Critical section of p_thread %d, count += %d → %d\n", my_id, my_id, count); fflush(stdout); // 把回合交给另一个线程 turn = other; // 非临界区 printf("Not critical section of p_thread %d\n", my_id); fflush(stdout); sleep(1); // 加个延迟,方便看交替效果 } pthread_exit(NULL); } int main(int argc, char *argv[]) { pthread_t p_thread1, p_thread2; struct arg_struct args_p_thread1 = {.my_id = 1, .other = 2}; struct arg_struct args_p_thread2 = {.my_id = 2, .other = 1}; pthread_create(&p_thread1, NULL, runner, (void*)&args_p_thread1); pthread_create(&p_thread2, NULL, runner, (void*)&args_p_thread2); // 主线程必须等子线程,不然直接退出杀线程 pthread_join(p_thread1, NULL); pthread_join(p_thread2, NULL); return 0; }
关键修复点
- 主线程等待子线程:用
pthread_join让主线程一直等,直到子线程结束(你的线程是无限循环,所以会一直跑下去,正好测试严格交替)。 - volatile修饰共享变量:防止编译器优化,确保每个线程都能看到最新的变量值。
- 刷新输出缓冲区:
fflush(stdout)解决printf因为行缓冲导致的输出延迟或不显示问题。 - 添加延迟:
sleep(1)让输出慢下来,能清楚看到两个线程严格交替进入临界区的效果。
内容的提问来源于stack exchange,提问作者A. Sousa
相关产品推荐
相关产品推荐

