您有兩個線程a和b。線程a處於永久循環中,監聽阻塞套接字1.線程b也處於永久循環中,監聽阻塞套接字2.套接字1和套接字2都可以在任意時間返回數據,所以線程a可能永遠處於休眠狀態等待數據,而線程b不斷從套接字獲取數據並繼續進行處理。這是背景。Haskell線程通信模式場景
現在假設他們需要共享一本字典。當線程a獲取一些數據(如果有的話)時,它會在處理完一些字典後將一個鍵值對添加到字典中,然後繼續等待更多數據。當線程b從套接字接收數據時,它首先查詢字典,以查看在處理之前是否存在與其接收到的數據有關的信息。字典中沒有刪除,只有插入和查詢(如果這對最終解決方案產生影響,我會感興趣)。
在像Python或C標準的命令式語言,這是很容易通過在這兩個領域中可用的字典,只查詢它一個線程已經獲得了鎖之後做的,所以線程B總是能看到最(以及幾乎)最新的字典。
在Haskell中,我似乎正在努力想出一個很好的實現這種模式。 MVars,一次只能有一個項目,所以它不能將線程放入字典中,因爲可能會發生新的更新,並且直到線程b從MVar中取得它才能夠推送新的字典。另一方面,如果線程b使用MVar發送準備好的信號「OK!」爲了線程化,可能出現這樣的情況:線程a正在其讀取套接字上休眠,所以它將無法發回數據,直到其讀取套接字解除阻塞!也有渠道,但這似乎很混亂,因爲我將不得不繼續發送新的字典,線程B將放棄除最後一個之外的所有。
可行的替代解決方案是簡單地向通道發送更新,並讓線程B爲其自身構建字典。不過,我想知道是否有更好的替代解決方案。
感謝您花時間閱讀這個非常長的問題!
我沒有看到'MVar'的問題。如果A喚醒並獲取新數據,它會嘗試從MVar中取出字典。當它成功時,更新字典,'putMVar'字典,回到睡眠狀態。當B獲得數據時,嘗試'takeMVar',查找放回。那個分解點在哪裏? – 2012-01-02 21:17:13
謝謝!拍攝對不起,這正是我正在尋找的,沒關係。我仍然是個開胃菜。我曾以爲如果放入它就不能取出,只有另一個線程可以。愚蠢的假設在我的腦後!我現在不確定如何解決這個問題? – 2012-01-02 21:19:32
我可以讓它成爲一個答案,您可以接受將問題標記爲已解決,或者如果您願意,可以刪除該問題(我不知道如何,應該有某處有刪除鏈接,我相信)。 – 2012-01-02 21:23:38