2009-01-17 33 views
4

如果鎖定確保一次只有一個線程訪問鎖定的數據,那麼控制對鎖定功能的訪問是什麼?鎖爲什麼工作?

我認爲boost::mutex::scoped_lock應該在我的每個函數的開始,所以本地變量不會被另一個線程意外修改,是正確的嗎?如果兩個線程在非常近的時間試圖獲得鎖,該怎麼辦?內部使用的鎖的局部變量不會被其他線程破壞嗎?

我的問題不是提升特定的,但我可能會使用,除非你推薦另一個。

回答

10

你是對的,在實現鎖定時需要一些方法來保證兩個進程不會同時獲得鎖定。要做到這一點,您需要使用原子指令 - 保證完成而不會中斷。一個這樣的指令是test-and-set,將獲得布爾變量的狀態,將其設置爲true並返回先前檢索的狀態的操作。

這樣做可以讓您編寫不斷測試的代碼,以查看它是否可以獲取鎖。假設x是線程之間共享變量:

while(testandset(x)); 
// ... 
// critical section 
// this code can only be executed by once thread at a time 
// ... 
x = 0; // set x to 0, allow another process into critical section 

由於其他線程不斷測試鎖,直到他們讓進了關鍵的部分,這是保證相互排斥的一種非常低效的方式。然而,使用這個簡單的概念,您可以構建更復雜的控制結構,如效率更高的信號量(因爲進程不循環,它們正在睡眠)

10

您只需擁有對共享數據的獨佔訪問權限。除非它們是靜態的或者堆中的,否則函數內部的局部變量對於不同的線程將具有不同的實例,並且不需要擔心。但是共享數據(例如通過指針訪問的東西)應該先鎖定。

至於鎖是如何工作的,它們經過精心設計以防止競爭條件,並且通常具有硬件級別支持以保證原子性。 IE,有一些機器語言結構保證是原子的。信號量(和互斥量)可以通過這些實現。

+0

謝謝我試圖找出函數是否有每個線程的單獨實例。但是,你能提供一個鏈接給你從這個信息來源嗎? – 2009-01-17 06:04:58

+0

我沒有函數變量的來源,對不起。但願我做了,可惜我沒有。其餘部分來自信號量維基百科文章。 – Sydius 2009-01-17 06:32:16

4

最簡單的解釋是,鎖定是基於硬件指令,它保證是原子的,不能在線程之間發生衝突。

函數中的普通局部變量已經專用於單個線程。只有靜態,全局或其他數據可以被多個線程同時訪問,而這些線程需要使用鎖來保護它。

0

操作鎖的機制控制對其的訪問。

任何鎖定原語需要能夠在處理器之間傳遞更改,因此它通常在總線操作(即讀取和寫入內存)之上實現。它也需要被構造爲使得兩個線程試圖聲明它不會破壞它的狀態。這並不容易,但您通常可以相信,任何操作系統實現的鎖都不會被多個線程破壞。