|
1
27
A.
使用联锁。增量和。递减
|
|
2
21
这是非常错误的。
即使编译器可以保证在x86上始终生成递增和递减的内存版本,这仍然不能保证原子性——两个CPU可能会同时修改变量并得到不一致的结果。该指令需要锁前缀来强制它是一个原子操作——默认情况下,编译器永远不会发出锁变体,因为它保证了操作是原子的,因此性能较低。 考虑以下x86汇编指令:
如果I最初为0,并且代码在两个内核上的两个线程上运行,那么两个线程完成后的值在法律上可以是1或2,因为不能保证一个线程在另一个线程完成写入之前完成读取,或者一个线程的写入甚至在其他线程读取之前可见。
|
|
|
3
4
你被教错了。
|
|
4
3
递增
如您所见,有3条指令(在其他平台上可能有所不同),在任何阶段,cpu都可以上下文切换到不同的线程,使变量处于未知状态。 |
|
|
5
2
不,您需要同步访问。在Windows上,您可以使用Interlocked增量()和Interlocked递减()轻松完成此操作。我相信其他平台也有类似的东西。 |
|
6
1
高级语言中的任何类型的递增/递减操作(是的,甚至
如果你的讲师指的是机器指令,增量和减量操作可能是原子操作。然而,在当今不断增长的多核平台上,这并不总是正确的,除非他们保证 coherency . |
|
|
7
0
|
|
|
8
0
在a 单处理机 机器,如果不使用虚拟内存,x++(右值忽略)很可能会在x86架构上转换为单个原子INC指令(如果x很长,则使用32位编译器时,该操作仅为原子)。此外,movsb/movsw/movsl是移动字节/字/长字的原子方式;编译器不倾向于使用这些作为分配变量的正常方式,但可以使用原子移动实用程序函数。如果在写入过程中发生页面错误,虚拟内存管理器的编写方式可能会使这些指令的行为原子化,但我认为这通常不能保证。
Dim OldValue as Integer
Do
OldValue = Variable
While Threading.Interlocked.CompareExchange(Variable, OldValue Xor 1, OldValue) OldValue
这种方法允许对新值应依赖于旧值的变量执行任何类型的原子更新。对于某些常见的操作,如递增和递减,有更快的替代方案,但CompareExchange也允许实现其他有用的模式。 重要注意事项:(1)保持循环尽可能短;循环时间越长,另一个任务在循环过程中遇到变量的可能性就越大,每次发生这种情况都会浪费更多的时间;(2)在线程之间任意分配的指定数量的更新将始终完成,因为强制一个线程重新执行循环的唯一方法是如果其他线程取得了有益的进展;但是,如果某些线程可以执行更新而不向前推进完成,则代码可能会被实时锁定。 |
|
|
JLosc · Powershell脚本因文件锁定而失败 2 年前 |
|
|
Sriram Umapthy · PostgreSql行级锁 2 年前 |
|
|
a a · 为什么在这个可重入锁示例中需要引用计数? 4 年前 |
|
|
JohnLBevan · 为什么原子语句上需要锁提示? 8 年前 |