目前用GCC研究了C/C++中的原子操作,发现内存中自然对齐的全局变量都有原子读写.
然而,我试图按位AND全局变量,并注意到它归结为一个read-modify-write序列,如果有多个线程对该字节值进行操作,这是很麻烦的.
经过一些研究,我 Select 了这两个例子:
C Example-GCC分机__sync_fetch_and_and
#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;
}
使用Atom fetch_and
的C++ Example-C++11
#include <iostream>
#include <atomic>
std::atomic<uint8_t> byteCpp(0xFF);
int main() {
byteCpp.fetch_and(0xF0);
std::cout << "Value of byteCpp: 0x" << std::hex << static_cast<int>(byteCpp.load()) << std::endl;
return 0;
}
其他例子也在后面,但它们似乎不那么直观,计算成本也更高.
使用pthread_mutex_lock
uint8_t byte = 0xFF;
pthread_mutex_t byte_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&byte_mutex);
byte &= 0xF0;
pthread_mutex_unlock(&byte_mutex);
使用互斥体lock_guard
#include <mutex>
uint8_t byte;
std::mutex byte_mutex;
void atomic_and() {
std::lock_guard<std::mutex> lock(byte_mutex);
byte &= 0xF0;
}
使用compare_exchange_weak
std::atomic<uint8_t> byte;
void atomic_and() {
uint8_t old_val, new_val;
do {
old_val = byte.load();
new_val = old_val & 0xF0;
} while (!byte.compare_exchange_weak(old_val, new_val));
}
Question个
对于多线程C/C++程序中的read-modify-write序列,最好的原子方法是什么?