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

操作共享counter的两个循环线程如何同步避免死循环?

问题根因
  • 共享变量counter的判断逻辑未放在锁保护范围内,存在竞态条件:当counter值为1时,两个线程都可能先在锁外判断counter != 0为真,进入循环块。其中一个线程先拿到锁将counter减为0后释放锁,另一个线程拿到锁后会继续将counter减为-1,后续判断counter != 0永远为真,程序陷入死循环。
  • 示例代码中counter初始值写错,需求是初始值为100,代码中写为int counter = 0,会导致线程直接不进入执行逻辑。
修复方案

调整循环逻辑,将counter的判断和修改操作全部放在锁的保护范围内,避免竞态问题,修改后代码如下:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

int counter = 100; // 修正初始值为100
pthread_mutex_t counter_mutex;

void *Thread1(void *vargs)
{
    while (1) {
        pthread_mutex_lock(&counter_mutex);
        // 所有对counter的读写操作都在持有锁时执行
        if (counter == 0) {
            pthread_mutex_unlock(&counter_mutex);
            break;
        }
        counter--;
        pthread_mutex_unlock(&counter_mutex);
    }

    sleep(1);
    printf("Completed Thread1\n");
    return NULL;
}

void *Thread2(void *vargs)
{
    while (1) {
        pthread_mutex_lock(&counter_mutex);
        if (counter == 0) {
            pthread_mutex_unlock(&counter_mutex);
            break;
        }
        counter--;
        pthread_mutex_unlock(&counter_mutex);
    }

    sleep(1);
    printf("Completed Thread2\n");
    return NULL;
}

int main(void)
{
    pthread_t tid[2];

    // 初始化互斥锁
    pthread_mutex_init(&counter_mutex, NULL);

    // 创建工作线程
    pthread_create(&tid[0], NULL, Thread1, NULL);
    pthread_create(&tid[1], NULL, Thread2, NULL);

    // 等待工作线程终止
    pthread_join(tid[0], NULL);
    pthread_join(tid[1], NULL);
    
    // 打印最终counter值
    printf("Counter is %d\n", counter);

    // 销毁互斥锁避免资源泄漏
    pthread_mutex_destroy(&counter_mutex);
    return 0;
}
补充说明

pthread_mutex 相关的锁操作自带内存屏障语义,能够保证共享变量在多线程间的可见性,不需要额外添加volatile关键字修饰counter。修改后程序运行时两个线程都会在counter减到0后正常退出,不会出现死循环问题。

内容的提问来源于stack exchange,提问作者Tony Hoan Trinh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:18:00