2016-05-17 69 views
1

我有一個解決某些問題的程序,我決定在一個不錯的GUI中監視它的功能。對於GUI,我選擇了Gtk這意味着我需要在專用線程中運行mainGUI循環,而我的程序的其餘部分將佔用不同的線程。我認爲我的程序和其他線程之間的通信將使用Chan向一個方向流動。我進一步決定使用FRP來更新工作者通知的GUI(原始程序在其單獨線程中的邏輯)。所以我嘗試編寫一個簡單的線程示例,其中一個線程將IO動作發送到執行操作(顯示它們)的監視線程。這裏是我的嘗試:來自線程之間共享通信通道的事件

import Control.Concurrent 
import Control.Monad 

import Reactive.Banana 
import Reactive.Banana.Frameworks 

main = do 
    c <- newChan 

    forkIO $ do 
     actuate <=< compile $ reactimate' 
          <=< changes 
          <=< fromPoll 
          $ readChan c 

    forever $ do 
     threadDelay 3000000 
     putStrLn "sending msg" 
     writeChan c $ putStrLn "receiving msg" 

這顯然是行不通的(只打印sending msg),否則我就不會在這裏。我究竟做錯了什麼?我需要一個與投票時間不同的事件嗎?怎麼做?

我期望一些文本副本的交錯:sending msgreceiving msg


爲了澄清我想從

main = do 
    c <- newChan 

    forkIO . forever . join . readChan $ c 

    forever $ do 
     threadDelay 3000000 
     putStrLn "sending msg" 
     writeChan c $ putStrLn "receiving msg" 

其中在線程明確地(可能阻塞)被讀入c :: Chan (IO())每個消息移動,消息的反應處理,即描述事件的網絡/行爲與GUI元素互連,然後讓線程執行GUI循環。網絡需要關注頻道中的輪詢值和觸發事件。


的解決方案,我正在尋求(或類似的東西):

main = do 
    (msgHandler, msgFire) <- newAddHandler 

    forkIO $ do 
     actuate <=< compile $ do 
      eMsg <- fromAddHandler msgHandler 

      reactimate $ putStrLn <$> eMsg 

    forever $ do 
     threadDelay 3000000 
     putStrLn "sending msg" 
     msgFire "receiving msg" 
+0

這可能是有益的:https://wiki.haskell.org/Haskell_for_multicores#Message_passing_channels – jkeuhlen

+0

謝謝,我對FRP一部分,而不是渠道雖然比較困惑。 – jakubdaniel

回答

2

fromPoll狀態

結果行爲將在每當事件,網絡處理的更新文檔輸入事件。

由於沒有事件,所以不會更新。 fromPoll作爲讀取可變數據的快捷方式而不是更新網絡。文檔建議我們使用fromChanges。但是既然我們或者因爲我們想要Event無論如何,讓我們使用newEvent,這看起來很合適:它允許我們創建一個Event,我們通過調用Handler(它是a -> IO()的別名)來添加值。

import Control.Concurrent 
import Control.Monad 

import Reactive.Banana 
import Reactive.Banana.Frameworks 

main = do 

    c <- newChan 

    network <- compile $ do 
     (event, handler) <- newEvent 
     liftIO $ forkIO $ forever (readChan c >>= handler) 
     reactimate event 

    forkIO $ actuate network 

    forever $ do 
     threadDelay 3000000 
     putStrLn "sending msg" 
     writeChan c $ putStrLn "receiving msg"