我曾经读过关于所谓的非原子和原子(在 VB 中:互锁)操作的非常好的解释,并将尝试总结一下。
Normal "non-atomic" operations consist of several steps
-> 其他线程可以在这些链之间工作
"Atomic" operations consist of one only one step
-> 处理原子操作时其他线程无法执行工作,原子操作总是作为整体处理
互锁类是此类原子操作的集合,因此根据定义是线程安全的。
即使多个线程对同一个变量执行读写操作,这些操作也是绝对线程安全的。
这些线程安全命令的组合仍然可能是不安全的,因为在原子操作之间可能会发生竞争条件。
因此,例如,如果您想比较 2 个变量,然后递增较小的变量,这不是线程安全的,即使它们自己的单个操作是 (interlocked.compare, interlocked.increment)。
在这里您仍然必须使用同步锁。
除此限制外,联锁没有“隐藏的不好的一面”。
a = 5 的竞态条件示例:
Thread1: a+=1
Thread2: a+=2
--> supposed to be 8, but can be only 6 or 7,
but can also be 6 or 7 depending on which thread wins the race
选项1:
T1 step 1: read 5
T1 step 2: add 1 = 6
T1 step 3: write 6
T2 step 1: read 6
T2 step 2: add 2 = 8
T2 step 3: write 8
--> is 8 as supposed
或选项 2:
T1 step 1: read 5
T2 step 1: read 5
T1 step 2: add 1 = 6
T2 step 2: add 2 = 7
T2 step 3: write 7
T1 step 3: write 6
--> is only 6
或选项 3:
T1 step 1: read 5
T2 step 1: read 5
T1 step 2: add 1 = 6
T2 step 2: add 2 = 7
T1 step 3: write 6
T2 step 3: write 7
--> is only 7
使用 interlocked.increment:
选项 1:
T1 step 1: read 5, add 1, write 6
T2 step 1: read 6, add 2, write 8
或选项 2:
T2 step 1: read 5, add 2, write 7
T1 step 1: read 7, add 1, write 8
-> 在所有情况下 a = 8,线程安全解决方案
这里发布的所有问题都可以通过将这个简单的示例应用于有问题的代码来解决。
希望这可以帮助其他在谷歌上搜索此主题的人。
贾尼斯