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

该函数是否需要加锁?关于pthread互斥锁读取64位变量的疑问

关于64位共享变量读取加锁的疑问

以下是原示例代码:

#include <pthread.h>

pthread_mutex_t count_mutex;
long long count;

void increment_count()
{
    pthread_mutex_lock(&count_mutex);
    count = count + 1;
    pthread_mutex_unlock(&count_mutex);
}

long long get_count()
{
    long long c;
    
    pthread_mutex_lock(&count_mutex);
    c = count;
    pthread_mutex_unlock(&count_mutex);

    return (c);
}

文档相关说明:

increment_count()函数使用互斥锁确保共享变量的原子更新,这一点合理。但文档称get_count()函数使用互斥锁保证64位变量count的原子读取,对此我有疑问:解锁count_mutex后,其他线程可调用increment_count()修改count,导致返回结果失效,这不可避免。那为何不直接写成无锁形式?

无锁版本代码:

long long get_count()
{
    return count;
}

解答

加锁的核心不是保证返回值永远有效,而是保证读取操作本身是原子且正确的,具体原因有这几点:

  1. 避免撕裂读:在32位系统上,64位变量的读取会拆成两次32位操作。如果不加锁,其他线程在两次操作之间修改变量,你读到的会是一个“半旧半新”的错误值,完全不符合变量在任意时刻的真实状态。
  2. 保证内存可见性:互斥锁的解锁操作会强制刷新CPU缓存,确保当前线程读到的count是内存中的最新值,而不是缓存里的过期数据。无锁读取可能因为缓存一致性问题,拿到旧值。
  3. 代码可移植性:就算64位系统硬件支持64位原子读取,加锁写法能兼容所有平台,不需要依赖特定硬件特性,代码在不同架构下都能正常工作。

至于你提到的“返回后值失效”,这是多线程环境的固有特性——任何共享变量的读取结果都只代表某个瞬间的状态,后续被修改是正常的。但加锁至少能保证你拿到的是那个瞬间的完整、正确的值,而不是一个错误的撕裂值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:22:55