2016-05-17 49 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"