2011-08-02 20 views
42

我已經看到TVar是一個簡單的容器,而TMVarMVar相同,這意味着它具有鎖等,但在STM monad中。我想知道爲什麼這是必要的,因爲STM的想法是不需要鎖。TVar和TMVar之間的區別

那麼,如果你有一個像[Handle]那樣的類型,你想在哪個線程之間使用的套接字句柄的列表是forkIO

回答

38

它並不真正鎖定的問題,這是關於參考的意思:

  • TVar是內STM一個可變的引用,較一般的共享狀態。你可以創建一個值,你可以讀取和寫入它,等等。它非常類似於IORefSTRef(反正它們是同樣的東西)。

  • TMVar是線程可用於通信的插槽的引用。它可以創建一個值,或者爲空。你可以給它添加一個值,如果已經填滿了,直到有人清空它;或者你可以從中獲得一個值,如果它已經是空的,直到有人填滿它爲止。這顯然類似於MVar,但對於許多常見用途,將其視爲用於通信生產者/消費者對的單元素隊列可能會更簡單。

總之,TVar是一般的共享狀態,如果你想原子更新從任意位置數據使用。 TMVar是一個同步原語,如果您希望某個線程等待某些東西變爲可用,而另一個等待某些東西需要,則使用它。

還注意到TChan,它大致實現爲在鏈表中每個前向鏈接也是TVar的持有位置,並且用作通信的無界隊列。

所有這些都可以以稍微不同的方式使用 - 當然,您可以在不刪除它的情況下查看TMVar的值,例如,如果您想要多個線程都等待單個資源變得可用,但它永遠不會「用完」。

19

TVarTMVar之間的差異沒有那麼大,因爲他們看 - 絕對不能媲美的IORefMVar之間的差異。

雖然MVar確實爲線程安全提供了一些鎖定,TMVar沒有任何意義! (沒有額外的鎖定)所有重要的功能都已經用STMTVar實現,所以TMVar a只是TVar (Maybe a)的一個簡短的功能,它配備了一些很好的功能(其中一些使用retry功能塊)。

無論是與retry阻塞是與STM精神兼容,以及是否排除某些STM的優勢(無死鎖等)是一個單獨的問題,我希望能看到更有經驗的人來回答。

+1

'retry'會導致死鎖?它回滾當前事務,然後阻塞,直到情況發生變化。它不(實際上不能)在交易中阻塞。 –

+6

雖然它在事務中間不會發生死鎖,但是可以創建永遠不會成功的事務,類似於創建經典死鎖的方式,例如兩個事務正在等待對方的結果。現在並不明顯,這與實踐中的僵局有何不同。 – Rotsor

+4

啊,對。我相信實際的術語恰恰就是「活鎖」。儘管如此,它更像是一種資源匱乏而不是僵局。鑑於死鎖可能很容易由於相同資源的不相關使用而產生,我相信STM的樂觀性使得活鎖不太可能發生,除非存在直接衝突或非常高的整體爭用。 –