亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如下程序,是關于TestAndSet()解決硬體同步的原理的問題

如下程序,是關于TestAndSet()解決硬體同步的原理的問題

PHP
小怪獸愛吃肉 2023-03-02 17:13:42
booleanTestAndSet (boolean *target){boolean rv = *target;*target = TRUE;return rv;}do{while(TestAndSet(&lock))criticalsection;lock= FALSE;remaindersection;}while (TRUE);
查看完整描述

2 回答

?
汪汪一只貓

TA貢獻1898條經驗 獲得超8個贊

這個函數還是十分精妙的!但是有點兒繞

首先糾正一下你代碼的錯誤,while(TestAndSet(&lock))之后是有個分號的,即

while(TestAndSet(&lock));

是個空語句,表示一直在這里死循環。而不是一個勁兒的運行criticalsection。下面說這個機制的原理。

一個線程運行到while(TestAndSet(&lock))這句的時候,

  1. 如果criticalsection沒有被鎖住,即lock值為false,那么傳入TestAndSet()的參數為false,【【在函數體內:rv先被賦為false,然后*target被賦為true,然后返回rv(值為false)。運行的結果為:返回值為false,使線程跳出while循環,得以進入criticalsection;同時參數(即lock)被改為true,表示criticalsection被鎖住】】,其他線程在當前線程沒有出criticalsection之前(即運行lock=false這句之前),不能進入criticalsection。為什么呢,下面說

  2. 如果線程運行到while(TestAndSet(&lock))時,criticalsection被鎖住了,即lock值為true,那么證明有其他線程在運行criticalsection的代碼(如第一步所說),那么傳入TestAndSet()函數的值為true,《《在函數體內:*target為傳入的值(true),rv被賦為true,*target被賦值為true(原來就是true,賦值不改變什么),返回rv。那么運行結果是返回值是rv(true),lock也是true。因為返回值是true,所以while繼續運行,lock還是true》》,所以傳入TestAndSet()的參數依然是true。在上一句《《》》之間的過程又重新運行一遍,然后一遍又一遍。所以這個線程一直在while這里一直運行,不能進入criticalsection。

    直到在criticalsection中的那個線程運行完criticalsection中的代碼,即運行到lock=false這句,lock被賦為false。這時比較關鍵了,while中再次運行TestAndSet()的時候傳入的參數變成了false,那么第一段中【【】】中的過程會運行一遍,即返回值為false,在while中運行了無數次的進程可以跳出while,進入criticalsection,lock又重新被賦為true,即鎖住criticalsection,其他進程此時不能進入。

所以“這條語句”的作用就是:如果當前criticalsection被鎖定,那么在這里等,直到解鎖;如果沒有被鎖定,當前進程可以進入criticalsection,同時鎖定criticalsection。

上面就是原理了,下面說硬同步。

之所以叫硬同步,是因為TestAndSet()函數中的三條語句是由硬件保證同步的,即硬件保證這三條語句必須原子運行,中間不發生任何中斷,如同一條語句。之所以這樣保證,是因為函數體內本身就是一個criticalsection,在多線程程序中,如果在這幾條語句中間被中斷,也會有race condition發生。


查看完整回答
反對 回復 2023-03-06
?
動漫人物

TA貢獻1815條經驗 獲得超10個贊

TestAndSet
  一個執行單元要想訪問被自旋鎖保護的共享資源,必須先得到鎖,在訪問完共享資源后,必須釋放鎖。如果在獲取自旋鎖時,沒有任何執行單元保持該鎖,那么將立即得到鎖;如果在獲取自旋鎖時鎖已經有保持者,那么獲取鎖操作將自旋在那里,直到該自旋鎖的保持者釋放了鎖。由此可以看出,自旋鎖是一種比較低級的保護數據結構或代碼片段的原始方式,這種鎖可能存在兩個問題:

  死鎖。試圖遞歸地獲得自旋鎖必然會引起死鎖:遞歸程序的持有實例在第二個實例循環,以試圖獲得相同自旋鎖時,不會釋放此自旋鎖。在遞歸程序中使用自旋鎖應遵守下列策略:遞歸程序決不能在持有自旋鎖時調用它自己,也決不能在遞歸調用時試圖獲得相同的自旋鎖。此外如果一個進程已經將資源鎖定,那么,即使其它申請這個資源的進程不停地瘋狂“自旋”,也無法獲得資源,從而進入死循環。
  過多占用cpu資源。如果不加限制,由于申請者一直在循環等待,因此自旋鎖在鎖定的時候,如果不成功,不會睡眠,會持續的嘗試,單cpu的時候自旋鎖會讓其它process動不了. 因此,一般自旋鎖實現會有一個參數限定最多持續嘗試次數. 超出后, 自旋鎖放棄當前time slice. 等下一次機會。

 


查看完整回答
反對 回復 2023-03-06
  • 2 回答
  • 0 關注
  • 129 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號