2013-12-16 62 views
4

我們有一個支持二進制插件(動態加載庫)的應用程序以及一些此應用程序的插件。該應用程序本身是多線程的,插件也可能啓動線程。有很多鎖定正在進行,以保持數據結構的一致性。多線程環境中的文檔鎖定

一個主要問題是,有時鎖從應用程序調用到插件中。這是有問題的,因爲插件代碼可能要回調到應用程序中,導致死鎖。由於不同的團隊在基本應用程序和插件上工作,這個問題更加嚴重。

問題是:除了編寫大量的純文本之外,是否存在「標準」或至少廣泛使用的記錄鎖定方案的方式?

+0

語言??????? – Ricibob

+0

英文?不,嚴重的是,我會對描述鎖定的語言不可知的方式最感興趣。如果您有針對特定語言的解決方案,請開火。 – arne

+1

遞歸鎖呢?找到一個可以被同一個線程多次鎖定的互斥鎖。 – 2014-03-25 17:19:26

回答

3

這是一個理論方法,我希望它能幫助你一點。

對我來說,通過重新設計插件和應用程序通信的方式(如果可能),可以避免這種情況。

插件的代碼不安全。爲確保應用程序的靈活性和穩定性,您必須構建一種標準方式來交換信息並通過插件進行關鍵操作。

最簡單的方法是避免通過定義無鎖api來管理每個特定的插件行爲。 要做到這一點,您可以使用環形緩衝區/干擾程序或只是一個動作緩衝區,使插件的關鍵部分異步。

編輯

很抱歉,如果我以同樣的方式再次爭論,但這似乎對我來說就像一個「IO」的問題。

對某些資源(內存/磁盤/網絡....不知道哪些資源)以及是否需要以高可用性對其進行公開訪問。最後,這些資源無法在未鎖定您的應用程序的情況下隨機訪問。

由於經理致力於關鍵部件,所以等待時間可以足夠短以致不可察覺。

但是,這並不容易適用於已經存在的應用程序,大多數情況下,如果它是一個大的應用程序。

如果你還不知道這種東西,我鼓勵你看看「干擾者」。對我而言,每次使用線程時都要考慮現代基礎知識之一。

+0

嗯,這本身就是一個很好的方法,但是無鎖是不可行的,因爲從插件返回到主應用程序的有問題的調用主要是查詢插件不能等待的信息。 – arne

2

我建議使用簡單易學的Petri網,並且可以很好地描述軟件不同部分之間的合作。在這個問題中描述了幾個有用的文件併發性的模型和工具:https://stackoverflow.com/questions/164187/what-tools-diagrams-do-you-use-for-modelling-multithreaded-systems。您可以根據需要選擇合適的型號。

+0

這似乎是最好的方法,但我擔心爲軟件系統寫下Petri網將會相當混亂。 – arne

+0

我知道,不幸的是每個模型都有一些優點和缺點。 我的建議是限制使用Petri Net來描述對共享資源的訪問,或者一般來說描述生產者 - 消費者之類的合作。爲了描述線程之間的同步,您可以使用UML活動圖,它非常好,易於理解。 –

2

如果您的鎖定方案足夠簡單以至於您可以在文檔中描述它,那麼通過所有方式都可以這樣做。但是,如果在實踐中發生死鎖,問題可能不是缺少文檔,但API不能滿足插件作者的需求。記錄限制是一個好的第一步,但消除這些限制會更好。

考慮對你的代碼舉行,由插件請求一個鎖死鎖的可能性:

  1. 你的代碼是不是在讀取或寫入中間,但仍持有該鎖只是因爲這就是代碼的寫法。在這種情況下,你的代碼在調用插件之前應該釋放鎖。
  2. 您的代碼和插件都讀取數據,並使用鎖來防止併發作者。在這種情況下,請使用讀寫器鎖定。
  3. 您的代碼正在更改數據,插件想要讀取它。這通常不安全;畢竟,你使用鎖來保護整個修改是有原因的。在實踐中,大多數嘗試使此安全失敗(這與編寫無鎖代碼一樣困難)。在這種情況下,最好的做法是更改設計,以便在調用插件之前代碼完成更改,或者在調用插件後開始更改。
  4. 您的代碼正在讀取數據,插件想要更改它。就像之前的情況一樣,這也是不安全的。你的代碼應該在調用插件之前釋放鎖,然後再次獲取它,並假定數據已經改變,重新讀取任何你需要繼續的內容。

這是最好的建議,我可以在不瞭解任何關於您的應用程序及其特定需求的更多信息。

對於大多數應用程序,軟件公司在相同的過程中迴避第三方二進制插件,因爲當出現問題時,很難找出原因。用戶通常責怪應用程序,而不是插件,並且對應用程序質量的看法很差。可以通過與插件作者保持非常密切的關係來工作,通常包括交換所有源代碼(可選地在限制性許可證或NDA下)。

+0

儘管這並沒有回答這個問題(我明確地詢問了文檔工具/技術),但它仍然考慮了一些優點。感謝您的洞察力。 – arne

1

是的,有一個標準的方式來記錄在大學使用的鎖定方案。 1 /使用圖表 您必須繪製圖表。圖中的每個點都是到其他線程的鎖定鏈接。

ex: T1  T2 
    1 -R-> A 
    2 <-W- B 

2 /使用表 你必須在每個點和線寫在每一行

ex: T1   T2 
    lockX(A) lockS(B) 
    read(A) read(B) 
    A<-A50  unlock(B) 

的結論是:這是非常複雜的任務,需要很多時間來追查。

+0

簡單但可能相當有效。 – arne