在这些条件下设置变量原子
Is Setting a Variable Atomic in THESE conditions
我有这种情况,我有一个状态变量;整数状态 = (2, 1, 0)
和一个无限循环:
ret = BoolCompareAndSwap(state, 1, 2)
if (ret) {
// Change something ...
state = 0;
}
这个状态设置是原子的吗?
假设要设置一个变量,您必须:
- Take out from memory
- Change value
- Set new value
如果其他线程来比较变量,它将是原子的,因为实际值不会改变,直到它在内存中重新设置,正确吗?
严格来说,如果按位写入状态,C 编译器仍然符合标准。写入前几位后,其他线程可以读取任何类型的垃圾。
大多数编译器不会做这样的事情(除了古老的 4 位处理器甚至更窄的处理器的编译器可能例外......),因为这会造成性能损失。
此外,更实际的是,如果任何其他线程写入(而不是仅读取)状态,如果您不保护所描述的代码免受竞争条件的影响,写入的值可能会丢失。
附带说明一下,所描述的状态更改(读取、修改、写入)从来都不是原子的。然而,当非原子性易受攻击时,这个问题是有效的,这就是我在上面试图回答的问题。
更一般地说,考虑并发访问的所有可能组合是一种有效的保护机制。然而,它在许多方面都非常昂贵(设计工作、测试工作、维护期间的风险......)。
只有当这些成本总计小于预期的节省(可能是性能)时,才可行,而不是使用适当的保护机制。
我有这种情况,我有一个状态变量;整数状态 = (2, 1, 0) 和一个无限循环:
ret = BoolCompareAndSwap(state, 1, 2)
if (ret) {
// Change something ...
state = 0;
}
这个状态设置是原子的吗? 假设要设置一个变量,您必须:
- Take out from memory
- Change value
- Set new value
如果其他线程来比较变量,它将是原子的,因为实际值不会改变,直到它在内存中重新设置,正确吗?
严格来说,如果按位写入状态,C 编译器仍然符合标准。写入前几位后,其他线程可以读取任何类型的垃圾。
大多数编译器不会做这样的事情(除了古老的 4 位处理器甚至更窄的处理器的编译器可能例外......),因为这会造成性能损失。
此外,更实际的是,如果任何其他线程写入(而不是仅读取)状态,如果您不保护所描述的代码免受竞争条件的影响,写入的值可能会丢失。
附带说明一下,所描述的状态更改(读取、修改、写入)从来都不是原子的。然而,当非原子性易受攻击时,这个问题是有效的,这就是我在上面试图回答的问题。
更一般地说,考虑并发访问的所有可能组合是一种有效的保护机制。然而,它在许多方面都非常昂贵(设计工作、测试工作、维护期间的风险......)。
只有当这些成本总计小于预期的节省(可能是性能)时,才可行,而不是使用适当的保护机制。