我有一个Windows 7驱动程序,我希望同步对变量的访问。我可以使用InterlockedExchange吗?
我目前对InterlockedExchange的理解是,InterlockedExchange是通过编译器内在函数完成的。这意味着,read(InterlockedExchange返回旧值)并且写入在一个时钟周期内完成。只有当变量总是通过互锁函数访问时,互锁函数才是原子的。
但在这种情况下会发生什么:
CPU1: InterlockedExchange(&Adapter->StatusVariable, 5);
CPU2: InterlockedExchange(&Adapter->StatusVariable, 3);
StatusVariable在两个CPU内核上以相同的时钟周期写入。该函数是否注意到该变量被访问并将写入推迟到不同的时钟周期?或者是否未定义写入后变量具有哪个值?变量是否也可能包含垃圾?
编辑:我在x86或x64上。
答案 0 :(得分:2)
InterlockedExchange生成一个具有隐式内存屏障的xchg指令。
Intel Instruction set reference是你的朋友:)有关锁如何工作的更多信息,请参阅第8章。
来自XCHG指令:
交换指令交换一个或多个操作数的内容,在某些情况下,执行其他操作,例如断言LOCK信号或修改EFLAGS寄存器中的标志。
XCHG(交换)指令交换两个操作数的内容。该指令取代了三个 MOV指令并不需要临时位置来保存一个操作数位置的内容 其他正在加载。当内存操作数与XCHG指令一起使用时,处理器的LOCK信号为 自动断言。因此,该指令对于实现信号量或类似的数据结构非常有用 进程同步。请参阅英特尔®64和64的“多处理器管理”第8章中的“总线锁定” IA-32架构软件开发人员手册,第3A卷,有关总线锁定的更多信息。
如果您对该参考有任何疑问,请询问。
答案 1 :(得分:1)
我有一个Windows 7驱动程序,我希望同步访问a 变量。我可以使用InterlockedExchange吗?
也许。也许不吧。这取决于您尝试做什么,变量代表什么以及当您说“同步访问”时您的期望是什么。
话虽如此,我怀疑答案是否定的,因为我看不出你在做什么算作同步。
这意味着,read(InterlockedExchange返回旧值)和 写操作在一个时钟周期内完成。
不完全是。互锁功能确保操作以原子方式进行。需要多少个时钟周期是另一个问题。忘记时钟周期。
只有当变量始终为时,互锁函数才是原子的 通过互锁功能访问。
这甚至意味着什么?
该函数是否注意到该变量被访问并推迟 写入不同的时钟周期?
更准确地说,处理器会注意到它。无论是将一个写入延迟到不同的时钟周期,您还关心什么?也许它确实如此,也许它没有。这个过程不属于你的业务。
在您的示例中,所有编译器和处理器都将保证,您需要知道的是:
InterlockedExchange(&Adapter->StatusVariable, 3);
之后Adapter->StatusVariable
的值将为3或5;和InterlockedExchange(&Adapter->StatusVariable, 5);
之后Adapter->StatusVariable
的值将为3或5。它将具有这两个值中的一个而没有其他值。您只是无法知道它将具有哪些值,并且应该明白为什么会这样。
或者是否未定义变量在写入后具有哪个值?
这取决于你对“未定义”的定义。目前还不清楚它将具有哪两个值,但它具有3
或5
,假设在该点之后没有其他线程正在改变该值。
变量是否也可能包含垃圾?
如果“垃圾”你指的是3
或5
以外的其他内容,那么在没有任何其他代码混淆价值的情况下,答案是明确的否< / strong>即可。变量将包含值3
或值5
。