2013-08-06 114 views
1

我有一個Windows 7驅動程序,我想同步對變量的訪問。我可以使用InterlockedExchange嗎?兩個CPU核心上的InterlockedExchange

我目前對InterlockedExchange的理解是,InterlockedExchange是通過編譯器內在函數完成的。這意味着,讀取(InterlockedExchange返回舊值)並且寫入在一個時鐘週期內完成。只有當變量總是通過互鎖功能訪問時,互鎖功能纔是原子的。

但在這種情況下會發生什麼:

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

StatusVariable被寫在兩個CPU核心相同的時鐘週期。該函數是否注意到變量被訪問並將寫入推遲到一個不同的時鐘週期?或者是不確定變量在寫入後具有哪個值?變量是否也可能包含垃圾?

編輯:我在x86或x64上。

回答

1

我有一個Windows 7驅動程序,我想同步訪問變量 。我可以使用InterlockedExchange嗎?

也許吧。也許不會。這取決於你想要做什麼,變量代表什麼,以及當你說「同步訪問」時你的期望是什麼。

這樣說,我懷疑答案是否定的,因爲我看不出你在做什麼算作同步。

這意味着,讀取(InterlockedExchange返回舊值)和 寫入在一個時鐘週期完成。

不完全是。互鎖功能確保操作以原子方式進行。需要多少個時鐘週期是另一個問題。忘記時鐘週期。

只有當通過互鎖功能訪問變量總是 時,互鎖功能纔是原子。

這是什麼意思?

該函數是否注意到變量被訪問並推遲 寫入不同的時鐘週期?

它更準確地說,處理器它的聲明。無論它是否將一個寫入不同的時鐘週期,您關心什麼?也許它確實,也許它沒有。這不關你的事。

所有的編譯器和處理器將保證在你的榜樣,所有你需要知道的是:

  1. 聲明InterlockedExchange(&Adapter->StatusVariable, 3);後的Adapter->StatusVariable值要麼是3或5;和
  2. 語句InterlockedExchange(&Adapter->StatusVariable, 5);後的Adapter->StatusVariable值要麼是3或5。

它將具有這兩個值並沒有其他值中的一個。你只是不能知道它會有哪些值,它應該很明顯,看看爲什麼。

或者它未定義變量在寫入後有哪些值?

這取決於你的「undefined」的定義我猜。目前還不清楚它將具有哪兩個值,但它有35,假設沒有其他線程正在更改該點後的值。

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

如果「垃圾」你的意思是比任何35其他的東西,然後,在沒有以該值弄亂任何其他代碼,答案是明確的沒有。該變量將包含值3或值5

+0

這裏沒有提到的重要一點是這些調用的返回值。使用互鎖的調用應該檢查返回的值。除非我誤認爲它是這樣的:可以說'StatusVariable'的初始值是2,然後(除非我錯了)那些調用中的一個將返回2,另一個將返回3或5,而兩次通話後的值分別爲5或3。哪個價值超出了你的控制範圍,而你應該根據舊的價值來採取行動 - 是否如預期的那樣,還是應該放棄/重試? (P.S.我可能是錯的。) – AnorZaken

0

我的直覺是,由於兩個CPU將在單獨的線程上執行這些命令,所以InterlockedExchange將阻塞一個線程,直到現有線程完成。

我不確定你需要擔心時鐘週期,更多關注線程。對不起,我不熟悉這一點,但我閱讀文檔和線程方面對我來說很突出。

2

InterlockedExchange生成一個具有隱式內存屏障的xchg指令。

Intel Instruction set reference是你的朋友:)有關鎖的工作原理的更多信息,請參閱第8章。

從XCHG指令:

交換指令交換的一個或多個操作數的內容,並且在一些情況下,執行附加的操作,諸如斷言LOCK信號或在EFLAGS修改標誌寄存器。

XCHG(交換)指令交換兩個操作數的內容。這條指令取代了三條指令,並且不需要臨時位置來保存一個操作數位置的內容,而另一個正在被加載。當內存操作數與XCHG指令一起使用時,處理器的LOCK信號自動置爲 。因此該指令對於實現進程同步的信號量或類似數據結構很有用。有關總線鎖定的更多信息,請參閱英特爾®64和 IA-32架構軟件開發人員手冊,卷3A的第8章「多處理器管理」中的「總線鎖定」。

如果您對參考文獻有任何疑問,請查詢。