簡體   English   中英

多線程和關鍵部分使用 - C ++

[英]Multithreading and Critical Sections Use - C++

關於在多線程應用程序中正確使用關鍵部分,我有點困惑。 在我的應用程序中,有幾個在線程之間共享的對象(一些循環緩沖區和一個串行端口對象)。 是否應將這些對象的訪問權限置於關鍵部分內,或僅在特定時間進行? 我懷疑只是在某些時候,因為當我嘗試用EnterCriticalSection / LeaveCriticalSection包裝每個用法時,我遇到了似乎是死鎖的情況。 您可能有任何見解將不勝感激。 謝謝。

如果您跨線程共享資源,並且其他一些線程在其他線程寫入時讀取,那么它必須始終受到保護。

如果不了解更多關於代碼的內容,很難提供更多建議,但這里有一些要記住的一般要點。

1)關鍵部分保護資源 ,而不是流程

2)在所有線程中以相同的順序輸入/離開關鍵部分。 如果線程A進入Foo,然后輸入Bar,則線程B必須以相同的順序輸入Foo和Bar。 如果你不這樣做,你可以創建一個種族。

3)進入和離開必須以相反的順序進行。 例如,由於您輸入了Foo然后進入了Bar,您必須在離開Foo之前​​離開Bar。 如果不這樣做,可能會造成死鎖。

4)合理地在最短的時間內保持鎖定。 如果你在開始使用Bar之前已經完成了Foo,那么在抓住Bar之前釋放Foo。 但是你仍然必須從上面牢記訂購規則。 在同時使用Foo和Bar的每個線程中,您必須以相同的順序獲取和釋放:

  Enter Foo
  Use Foo
  Leave Foo
  Enter Bar
  Use Bar
  Leave Bar

5)如果你只讀了99.9%的時間並寫了0.1%的時間,不要試圖聰明。 即使你只是在閱讀,你仍然必須進入暴擊秒。 這是因為當你在閱讀過程中時,你不希望寫入開始。

6)保持關鍵部分的細化。 每個關鍵部分應該保護一個資源,而不是多個資源。 如果你使關鍵部分太“大”,你可以序列化你的應用程序或創建一組非常神秘的死鎖或種族。

在支持RAII的關鍵部分周圍使用C ++包裝器:

{
    CriticalSectionLock lock ( mutex_ );

    Do stuff...
}

鎖的構造函數獲取互斥鎖,即使拋出異常,析構函數也會釋放互斥鎖。

盡量不要一次獲得超過一個鎖,並盡量避免在持有鎖時調用類外的函數; 這有助於避免在不同的地方獲得鎖定,因此您可以減少死鎖的可能性。

如果您必須同時獲得多個鎖,請按地址對鎖進行排序並按順序獲取。 這樣,多個進程在沒有協調的情況下以相同的順序獲得相同的鎖。

使用IO端口,考慮是否需要在輸入的同時鎖定輸出 - 通常情況下有一些東西試圖寫入,然后期望讀取,反之亦然。 如果你有兩個鎖,那么你可以在一個線程寫入然后讀取時獲得死鎖,然后另一個讀取然后寫入。 通常有一個執行IO的線程和一個請求隊列解決了這個問題,但這比僅使用鎖包裝調用要復雜一點,而且沒有更多細節我不推薦它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM