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

C语言Pthread互斥锁9读1写场景未生效,求助锁函数正确调用位置

Pthread互斥锁异常问题排查与修复

根因分析

Pthread互斥锁是协作式同步原语,不会自动为共享资源加上访问屏障,只有所有访问共享资源的线程都主动申请持有锁,才能保证互斥访问。
你当前代码的问题仅出在读线程侧:9个读线程访问共享数组array时没有申请锁,直接读取内存数据,自然能读到写线程持有锁修改过程中的中间状态(数组元素被置0但还未回填正确值的状态)。

互斥锁正确调用方式

所有访问共享资源(本次示例中是array数组)的线程,无论读、写操作,都必须遵循如下执行流程:

  1. 访问共享资源前调用pthread_mutex_lock(&lock)申请锁
  2. 访问共享资源
  3. 访问结束后立即调用pthread_mutex_unlock(&lock)释放锁

你现有代码中写线程的锁调用位置是正确的,已经完整覆盖了数组修改的原子区间,仅需要补充读线程的加锁逻辑即可。

修正后可运行代码

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>

#define NUM_THREADS 10

pthread_mutex_t lock;
int array[1000] = {0};
pthread_t threads[NUM_THREADS];

int change_array(int *array)
{
    int arrayhelper[1000] = {0};
    
    for (int i = 0; i < 1000; ++i)
        arrayhelper[i] = i;
    
    pthread_mutex_lock(&lock);
    for (int i = 0; i < 1000; ++i)
        array[i] = 0;
        
    for (int i = 0; i < 1000; ++i)
        array[i] = arrayhelper[i];
    pthread_mutex_unlock(&lock);    

    return 1;
}

void *read_array(){
    while(1) {
        // 读操作前加锁
        pthread_mutex_lock(&lock);
        if (array[10] == 0)
            printf("%d failed to lock!\n", array[10]);
        // 读操作结束解锁
        pthread_mutex_unlock(&lock);
        // 可选:加短休眠避免线程空转占满CPU
        usleep(100);
    }
}

void *write_array(){
    while(1)
    {
        sleep(1);
        change_array(array);
    }
}

int main (){
    pthread_mutex_init(&lock, NULL);
    
    for (int i = 0; i < 1000; ++i)
        array[i] = i;

    pthread_create(&threads[0], NULL, *write_array, NULL);
    pthread_create(&threads[1], NULL, *read_array, NULL);
    pthread_create(&threads[2], NULL, *read_array, NULL);
    pthread_create(&threads[3], NULL, *read_array, NULL);
    pthread_create(&threads[4], NULL, *read_array, NULL);
    pthread_create(&threads[5], NULL, *read_array, NULL);
    pthread_create(&threads[6], NULL, *read_array, NULL);
    pthread_create(&threads[7], NULL, *read_array, NULL);
    pthread_create(&threads[8], NULL, *read_array, NULL);
    pthread_create(&threads[9], NULL, *read_array, NULL);

    pthread_join(threads[0], NULL);
    pthread_join(threads[1], NULL);
    pthread_join(threads[2], NULL);
    pthread_join(threads[3], NULL);
    pthread_join(threads[4], NULL);
    pthread_join(threads[5], NULL);
    pthread_join(threads[6], NULL);
    pthread_join(threads[7], NULL);
    pthread_join(threads[8], NULL);
    pthread_join(threads[9], NULL);

    pthread_mutex_destroy(&lock);
    
    pthread_exit(NULL);

    return 1;
}

修正后读线程必须持有锁才能读取数组内容,写线程修改数组时持有锁,读线程会阻塞在锁申请步骤,等写线程修改完成释放锁后才能拿到锁读取,此时数组已经完成全部回填,array[10]值为10,不会触发打印逻辑,符合预期。

内容的提问来源于stack exchange,提问作者saeid keneshli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:15:03