我有一個解決某些問題的程序,我決定在一個不錯的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 msg
和receiving 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"
這可能是有益的:https://wiki.haskell.org/Haskell_for_multicores#Message_passing_channels – jkeuhlen
謝謝,我對FRP一部分,而不是渠道雖然比較困惑。 – jakubdaniel