我有一个解决某些问题的程序,我决定在一个不错的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