1

我有一个 Windows 7 驱动程序,我想在其中同步对变量的访问。我可以使用 InterlockedExchange 吗?

我目前对 InterlockedExchange 的理解是,InterlockedExchange 是通过编译器内在函数完成的。这意味着,读取(InterlockedExchange 返回旧值)和写入在一个时钟周期内完成。仅当始终通过互锁函数访问变量时,互锁函数才是原子的。

但是在这种情况下会发生什么:

CPU1: InterlockedExchange(&Adapter->StatusVariable, 5);
CPU2: InterlockedExchange(&Adapter->StatusVariable, 3);

StatusVariable 在两个 CPU 内核上以相同的时钟周期写入。函数是否注意到变量被访问并将写入推迟到不同的时钟周期?还是未定义变量在写入后具有哪个值?变量是否也可能包含垃圾?

编辑:我在 x86 或 x64 上。

4

2 回答 2

2

InterlockedExchange 生成具有隐式内存屏障的 xchg 指令。

英特尔指令集参考是您的朋友 :) 有关锁如何工作的更多信息,请参阅第 8 章。

来自 XCHG 指令:

交换指令交换一个或多个操作数的内容,并且在某些情况下,执行附加操作,例如断言 LOCK 信号或修改 EFLAGS 寄存器中的标志。

XCHG(交换)指令交换两个操作数的内容。该指令取代了三个 MOV 指令,并且在加载另一个操作数位置时不需要临时位置来保存一个操作数位置的内容。当内存操作数与 XCHG 指令一起使用时,处理器的 LOCK 信号自动置位。因此,该指令对于实现信号量或用于进程同步的类似数据结构很有用。有关总线锁定的详细信息,请参阅 Intel® 64 和 IA-32 架构软件开发人员手册第 3A 卷第 8 章“多处理器管理”中的“总线锁定”。

如果您对参考有任何疑问,请询问。

于 2013-08-06T11:48:54.387 回答
1

我有一个 Windows 7 驱动程序,我想在其中同步对变量的访问。我可以使用 InterlockedExchange 吗?

也许。也许不吧。这取决于您要做什么,变量代表什么以及您说“同步访问”时的期望是什么。

话虽如此,我怀疑答案是否定的,因为我看不出你在做什么算作同步。

这意味着,读取(InterlockedExchange 返回旧值)和写入在一个时钟周期内完成。

不完全是。联锁功能确保操作以原子方式发生。需要多少时钟周期是另一个问题。忘记时钟周期。

仅当始终通过互锁函数访问变量时,互锁函数才是原子的。

那有什么意思?

函数是否注意到变量被访问并将写入推迟到不同的时钟周期?

更准确地说,处理器注意到了,它确实做到了。是否将一次写入推迟到不同的时钟周期,您在乎什么?也许会,也许不会。该流程的作用与您无关。

所有编译器和处理器都将在您的示例中保证,您需要知道的是:

  1. 在语句之后InterlockedExchange(&Adapter->StatusVariable, 3);,值Adapter->StatusVariable将是 3 或 5;和
  2. 在语句之后InterlockedExchange(&Adapter->StatusVariable, 5);,值Adapter->StatusVariable将是 3 或 5。

它将具有这两个值之一,没有其他值。您只是无法知道它将具有哪些值,并且应该很明显可以看出为什么会这样。

还是未定义变量在写入后具有哪个值?

我猜这取决于您对“未定义”的定义。目前尚不清楚它将具有这两个值中的哪一个,但它具有35假设在该点之后没有其他线程正在更改该值。

变量是否也可能包含垃圾?

如果你所说的“垃圾”是指任何其他的东西35那么在没有任何其他与该值混淆的代码的情况下,答案是明确的no。该变量将包含 value3或 value 5

于 2013-10-12T08:17:27.063 回答