是否在新标准C ++原子增量操作中使用检查前置条件增加值之前,原子值是否小于指定值?
我可以比以下代码更容易,更快地完成吗?
int atomic_inc(std::atomic_int& val, int less_than) {
int new_val;
int old_val = val.load();
do
{
if (old_val > less_than) return old_val;
new_val = old_val + 1;
} while (!val.compare_exchange_weak(old_val, new_val));
return new_val;
}
如果有人不知道compare_exchange_weak是如何工作的: compare_exchange_weak读取val,与old_val进行比较,如果它们不相等,则将val保存到old_val。如果它相等则将new_val保存到val。
答案 0 :(得分:1)
不,没有特别支持递增小于值的值。您的代码尽可能高效。 C ++ 11中没有等待的变体
无限数量的可能“增量如果X”模式。硬件制造商决定“只要不改变就增加”是他们唯一需要支持的东西。
理论上你可以为它创建一个带有特殊汇编代码的硬件平台,但是C ++ 11并没有直接针对它。
答案 1 :(得分:1)
我过去做过的事情可能会对你有用,具体取决于你使用的是什么。
如果您可以假设val
不会经常剪辑 - 那么可能优化不执行CAS也不会为您节省太多 - ,您可以盲目地增加值和阅读后调整它:
int atomic_inc(std::atomic_int& val, int less_than) {
return std::min(++val, less_than);
}
然后,如果需要,偶尔会将val
剪切回less_than
,这通常足以让您不必担心int
溢出,而且您是黄金。
答案 2 :(得分:-3)
如果您正在使用线程,则可以使用互斥锁进行原子增量。在这种情况下,你就是这样做的:
全局声明并初始化互斥:
pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL)
在一个帖子中:
int atomic_inc(std::atomic_int& val, int less_than) {
pthread_mutex_lock(&lock);
int newVal = val.load();
if (newVal < less_than)
newVal++
pthread_mutex_unlock(&lock);
return new_val;
}
在修改任何其他线程中的val
之前,您必须锁定和解锁互斥锁。
有关互斥锁的更多信息:http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#SYNCHRONIZATION