【问题标题】:Events from shared communication channel between threads来自线程间共享通信通道的事件
【发布时间】:2016-05-17 13:40:58
【问题描述】:

我有一个程序可以解决一些问题,我决定用一个漂亮的 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"

【问题讨论】:

  • 这可能会有所帮助:wiki.haskell.org/…
  • 谢谢,我更困惑的是 FRP 部分而不是通道。

标签: multithreading haskell reactive-banana


【解决方案1】:

fromPoll 状态的文档

每当事件网络处理输入事件时,都会更新生成的行为。

由于没有事件,它永远不会更新。 fromPoll 旨在作为一种快速而肮脏的方式来读取可变数据,而不是更新网络。相反,文档建议我们使用fromChanges。但是因为我们或者,因为我们无论如何都想要Event,所以让我们使用newEvent,这似乎很合适:它允许我们创建一个Event,我们通过调用Handler(这是一个别名a -&gt; 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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多