保证原子性的单位操作
Single bit manipulations with guaranteed atomicity
有没有办法在 C++ 中设置、清除、测试和翻转单个位作为原子操作?例如 "compare_and_swap" 的按位变体。
翻转一个整数位只是一个比较和交换操作。你用它来测试和翻转一个位不会改变任何东西。所以一个简单的 compare_exchange_weak
循环就可以做到这一点。
以原子方式操作位需要 compare_exchange
RMW 以避免触及 atomic
变量中的其他位。
测试一点不是修改操作,因此 load()
就足够了。
您将必须添加范围错误检查
template<typename T, typename OP>
T manipulate_bit(std::atomic<T> &a, unsigned n, OP bit_op)
{
static_assert(std::is_integral<T>::value, "atomic type not integral");
T val = a.load();
while (!a.compare_exchange_weak(val, bit_op(val, n)));
return val;
}
auto set_bit = [](auto val, unsigned n) { return val | (1 << n); };
auto clr_bit = [](auto val, unsigned n) { return val & ~(1 << n); };
auto tgl_bit = [](auto val, unsigned n) { return val ^ (1 << n); };
int main()
{
std::atomic<int> a{0x2216};
manipulate_bit(a, 3, set_bit); // set bit 3
manipulate_bit(a, 7, tgl_bit); // toggle bit 7
manipulate_bit(a, 13, clr_bit); // clear bit 13
bool isset = (a.load() >> 5) & 1; // testing bit 5
}
有没有办法在 C++ 中设置、清除、测试和翻转单个位作为原子操作?例如 "compare_and_swap" 的按位变体。
翻转一个整数位只是一个比较和交换操作。你用它来测试和翻转一个位不会改变任何东西。所以一个简单的 compare_exchange_weak
循环就可以做到这一点。
以原子方式操作位需要 compare_exchange
RMW 以避免触及 atomic
变量中的其他位。
测试一点不是修改操作,因此 load()
就足够了。
您将必须添加范围错误检查
template<typename T, typename OP>
T manipulate_bit(std::atomic<T> &a, unsigned n, OP bit_op)
{
static_assert(std::is_integral<T>::value, "atomic type not integral");
T val = a.load();
while (!a.compare_exchange_weak(val, bit_op(val, n)));
return val;
}
auto set_bit = [](auto val, unsigned n) { return val | (1 << n); };
auto clr_bit = [](auto val, unsigned n) { return val & ~(1 << n); };
auto tgl_bit = [](auto val, unsigned n) { return val ^ (1 << n); };
int main()
{
std::atomic<int> a{0x2216};
manipulate_bit(a, 3, set_bit); // set bit 3
manipulate_bit(a, 7, tgl_bit); // toggle bit 7
manipulate_bit(a, 13, clr_bit); // clear bit 13
bool isset = (a.load() >> 5) & 1; // testing bit 5
}