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

C/C++中原子性按位与操作字节的最优方法是什么?

多线程C/C++中读-改-写序列的最优原子操作方案

对于读-改-写类型的原子操作(比如你提到的按位与),最优方案是使用对应语言标准原生的原子库方法,具体分场景如下:

推荐方案

C++(C++11及以后)

直接使用<atomic>库中std::atomic<T>的fetch_and成员函数,这是标准规定的原子读-改-写操作,编译器会针对目标硬件生成最优的原子指令(比如x86平台的LOCK AND,ARM平台的LDREX/STREX组合),性能拉满且代码简洁可移植。

示例代码:

#include <iostream>
#include <atomic>

std::atomic<uint8_t> byteCpp(0xFF);

int main() {
    // fetch_and会原子执行 读-按位与-写,返回操作前的旧值
    byteCpp.fetch_and(0xF0);
    std::cout << "Value of byteCpp: 0x" << std::hex << static_cast<int>(byteCpp.load()) << std::endl;
    return 0;
}

C语言(C11及以后)

优先使用C11标准<stdatomic.h>中的atomic_fetch_and函数,同样是标准实现,跨平台性优于编译器扩展。如果项目必须兼容不支持C11的老版本GCC,再退而使用GCC扩展__sync_fetch_and_and。

标准C示例:

#include <stdio.h>
#include <stdatomic.h>
#include <stdint.h>

atomic_uint8_t byteC = ATOMIC_VAR_INIT(0xFF);

int main() {
    atomic_fetch_and(&byteC, 0xF0);
    printf("Value of byteC: 0x%X\n", atomic_load(&byteC));
    return 0;
}

老GCC兼容的扩展示例(仅作兼容用):

#include <stdio.h>
#include <stdint.h>

uint8_t byteC = 0xFF;

int main() {
    __sync_fetch_and_and(&byteC, 0xF0);
    printf("Value of byteC: 0x%X\n", byteC);
    return 0;
}

其他方案的劣势分析

互斥锁方案(pthread_mutex/std::lock_guard)

这类方案是通过锁将读-改-写逻辑包裹为临界区,性能远低于原子指令:当存在线程竞争时,锁会触发内核态切换,开销是原子指令的数十到上百倍。仅适合复杂的多操作临界区,不适合单一的读-改-写原子操作。

compare_exchange_weak循环

这是用自旋方式模拟原子操作,虽然是用户态操作,但效率不如原生fetch_and:每次竞争失败都需要重新读取值并计算新值,而原生fetch_and是硬件直接支持的单条原子指令,一次操作即可完成。仅当标准库没有提供对应原子操作(比如自定义复合逻辑)时,才需要用这种方式模拟。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:20:30