C语言如何使用mutex互斥锁正确实现多线程同步?
问题修复方案
代码现存错误梳理
- 变量名拼写错误:结构体
struct count定义的成员是no,但代码中全部误用为nr;循环判断条件写为N0_THREADS(数字0),实际宏定义是NO_THREADS(字母O) - 语法错误:
printf语句缺少参数分隔逗号,pthread_create调用第一个参数未传线程ID地址,且该行多了冗余右括号 - 缓冲区问题:
printf输出末尾未加换行符,标准输出默认行缓冲,未触发刷新时会导致多个线程的输出内容粘连,看起来像竞态 - 互斥锁使用错误:加锁后未调用
pthread_mutex_unlock释放锁,第一个线程持有锁后其余线程永远无法获取锁,是同步失效的核心原因 - 资源泄漏:
malloc申请的struct count内存、初始化的互斥锁均未主动释放
互斥锁正确使用规范
互斥锁用于保护多线程并发访问的共享资源(本例中是标准输出stdout),必须遵循:
- 进入临界区(访问共享资源的代码段)前加锁
- 临界区操作完成后必须立即释放锁,否则其余线程会永久阻塞在加锁逻辑
- 所有访问同一共享资源的线程都要遵守同一套加锁/解锁规则
修正后完整代码
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #define MAX_RESOURCE 5 #define NO_THREADS 5 int res_available = MAX_RESOURCE; pthread_mutex_t mtx; struct count { int no; }; void *use_res(void *v) { // 进入临界区前加锁 pthread_mutex_lock(&mtx); struct count *p = (struct count *) v; // 加\n触发行缓冲刷新,避免输出粘连 printf("--thread no %d :\n", p->no); // 临界区操作完成立即释放锁 pthread_mutex_unlock(&mtx); free(p); // 释放动态申请的内存,避免泄漏 return NULL; } int main(){ pthread_t thr[NO_THREADS]; pthread_mutex_init(&mtx, NULL); for(int i=0; i<NO_THREADS; i++){ struct count *c = malloc(sizeof(struct count)); c->no = i; // 修正传参和语法错误 pthread_create(&thr[i], NULL, use_res, c); } for(int i=0; i<NO_THREADS; i++) { pthread_join(thr[i], NULL); } pthread_mutex_destroy(&mtx); // 销毁互斥锁释放资源 return 0; }
修正后运行会按线程获取锁的顺序依次打印线程编号,不会出现输出乱序、竞态问题。
内容的提问来源于stack exchange,提问作者Dragos Polifronie
相关产品推荐
相关产品推荐

