You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言如何使用mutex互斥锁正确实现多线程同步?

问题修复方案

代码现存错误梳理

  • 变量名拼写错误:结构体struct count定义的成员是no,但代码中全部误用为nr;循环判断条件写为N0_THREADS(数字0),实际宏定义是NO_THREADS(字母O)
  • 语法错误:printf语句缺少参数分隔逗号,pthread_create调用第一个参数未传线程ID地址,且该行多了冗余右括号
  • 缓冲区问题:printf输出末尾未加换行符,标准输出默认行缓冲,未触发刷新时会导致多个线程的输出内容粘连,看起来像竞态
  • 互斥锁使用错误:加锁后未调用pthread_mutex_unlock释放锁,第一个线程持有锁后其余线程永远无法获取锁,是同步失效的核心原因
  • 资源泄漏:malloc申请的struct count内存、初始化的互斥锁均未主动释放

互斥锁正确使用规范

互斥锁用于保护多线程并发访问的共享资源(本例中是标准输出stdout),必须遵循:

  1. 进入临界区(访问共享资源的代码段)前加锁
  2. 临界区操作完成后必须立即释放锁,否则其余线程会永久阻塞在加锁逻辑
  3. 所有访问同一共享资源的线程都要遵守同一套加锁/解锁规则

修正后完整代码

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 21:24:06