CAS操作(Compare and Swap)用于实现线程间的同步和并发,它可以将多线程的操作变为原子操作。
CAS操作的作用是在多线程环境下保证数据的安全性,防止多个线程同时修改同一个变量而产生的竞争条件。简单来说,就是先比较当前内存中的值和期望值是否一致,如果一致则将该值更新为新的值,否则不进行操作。
下面分别给出两个用例进行说明:
第一个用例:
int i = 10; // 假设i的初始值为10
bool isEqual = false;
while(!isEqual) {
int oldValue = i;
int newValue = oldValue + 1; // 假设我们希望将i的值加1
isEqual = compareAndSwap(&i, oldValue, newValue); // 判断当前值和旧值是否一致
// 如果一致,则将旧值更新为新值
if(isEqual) {
i = newValue;
}
}
printf("最终i的值为:%d\n", i);
解释:在该用例中,我们希望将变量i的值加1,我们通过CAS操作来实现这个目的。首先在while循环中,我们获取变量i的值,并计算出期望修改后的新值。然后通过compareAndSwap函数来比较当前内存中的值和期望值是否一致,如果一致则将该值更新为新的值,否则不进行操作。最终,我们输出变量i的值。
第二个用例:
int i = 10; // 假设i的初始值为10
atomic<int> atomicI(i);
int oldValue = atomicI.load(); // 获取当前内存中的值
int newValue = oldValue + 1; // 假设我们希望将i的值加1
while(!atomicI.compare_exchange_weak(oldValue, newValue)) {
// 如果当前值和旧值不一致,则重新获取当前值进行比较
oldValue = atomicI.load();
newValue = oldValue + 1;
}
printf("最终i的值为:%d\n", atomicI.load());
解释:在该用例中,我们同样希望将变量i的值加1,但是我们使用了C++ STL标准库中的atomic模板。首先通过atomic<int> atomicI(i);
来创建原子变量,然后通过atomicI.load()
来获取当前内存中的值,并计算出期望修改后的新值。接着,在while循环中,我们通过atomicI.compare_exchange_weak(oldValue, newValue)
来比较当前内存中的值和期望值是否一致,如果一致则将该值更新为新的值,否则重新获取当前内存中的值进行比较。最终,我们输出变量i的值。
通过以上两个用例,我们可以看到CAS操作虽然比一般的加锁操作更加高效,但同时也需要我们更加谨慎。因为一旦CAS操作失败,我们需要重新取得当前值,再次进行比较,这会带来额外的开销。所以在使用CAS操作时,我们需要仔细考虑每一个细节,确保其正确性和高效性。