原子compare_exchange,但基于正在设置的标志,而不是相等
Atomic compare_exchange, but based on flag being set, rather than equality?
std::atomic提供compare_exchange_strong(a,b)测试底层值当前是否为"a",如果是,则以原子/线程安全的方式将其替换为"b"。
是否有任何无锁的原子方式来执行类似的操作,但它不会测试与"b"的相等性,而是将"b"视为一个标志,并在基础值设置了该标志的情况下执行替换?
所以原则上,类似的东西
bool compare_exchange_flags(std::atomic<int>& underlying, int& flag, int replacement)
{
auto tmp = underlying.load();
if((tmp & flag) == flag) // only perform replacement if flag is set
{
flag = tmp; // emulate compare_exchange_strong, where expected value is replaced with actual value
underlying = replacement;
return true;
} else {
flag = underlying.load();
return false;
}
}
只有在一个版本中。。好吧,实际工作;)(当然,上述操作根本不是原子操作)
谢谢!
对于上下文:这是用于消息总线。该总线具有与某些状态(如READABLE、WRITEABLE)相关联的内存区域。
每个状态都需要通过一些标志来增强——例如,一个状态可以是"WRITEABLE",这意味着写入程序可以自由地将数据写入片段(读取器当前正在旋转/忙于轮询)。或者它可以是"WRITEABLE|SIGNALED",这意味着写入者可以获取该内存进行写入,但需要在写入数据后触发事件来通知读者。
所以(从概念上讲,这不是真正的代码——只是为了大致演示)类似的东西
void send(...)
{
auto expected = WRITEABLE;
if(compare_exchange_flags(status, expected, WRITE_RESERVED))
{
// ... write data ...
status = WRITTEN;
if((expected & SIGNALED) = SIGNALED)
wakeUpReaders();
} else {
tryAnotherRegion();
}
}
没有这样的指令。但这种操作通常是用一个循环来执行的,该循环试图在值具有标志时交换值:
bool replace_if_flag(std::atomic<int>& underlying, int flag, int replacement){
auto tmp = underlying.load();
if(!(tmp & flag)) return false;
while (!underlying.compare_exchange_weak(tmp,replacement)){
if(!(tmp & flag)) return false;
}
return true;
}
相关文章:
- 在 CMake 中为每个目标设置编译器/链接器标志
- 如何正确设置 ios 标志以进行流操作?
- 有关使用标志位设置内部错误标志的说明
- 如何在CMakeLists.txt中正确设置CMake标志
- 设置用于调试的 g++ 编译器标志
- 如何在Qt中取消设置标志?
- SDL_CreateWindow在设置标志时失败SDL_WINDOW_VULKAN
- 如何在 cmake 中设置编译器特定的标志
- 如何在图像位中设置标志以标记音频文件的结尾
- 添加 swig pythoncode 以在 Python 对象上设置自己的标志
- 如何在cmake中的源文件之后设置库标志?
- 为什么我必须将错误状态标志设置为 goodbit 才能使其工作
- while 循环是否在设置标志的情况下运行多次?
- 设置 Xcode 标志以便将 python 嵌入我的C++项目中
- STD :: Ostream忽略了通过setf()在基础上设置的十六进制标志
- 如何嵌入在C++中设置标志的 python 代码
- 检查是否为输入流设置了Skipws/noskipws标志
- Dlib:如何初始化一个忽略标志设置为1的mmodrect
- Cmake没有将汇编程序标志设置为armasm(对于WinCE)
- 调用WinHttpCreateUrl与ICU_REJECT_USERPWD标志设置在Windows 7中工作,但不Win