У меня есть программа, которая решает какую-то проблему, и я решил, что хочу следить за тем, что она делает, в удобном графическом интерфейсе. Для графического интерфейса я выбрал Gtk
, что означает, что мне нужно запустить цикл mainGUI
в выделенном потоке, а остальная часть моей программы займет другой поток. Я думал, что связь между моей программой и другим потоком будет проходить в одном направлении, используя Chan
. Далее я решил использовать FRP для обновления графического интерфейса при уведомлении от воркера (логика оригинальной программы в отдельном потоке). Поэтому я попытался написать простой пример с потоками, в котором один поток отправляет 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 ())
читается в потоке явно (возможно, с блокировкой) для реактивной обработки сообщений, т. е. описания сети событий/поведений, связанных с элементами графического интерфейса, а затем позволяет потоку выполнять цикл графического интерфейса. Сеть должна будет позаботиться о значениях опроса в канале и запускающих событиях.
Решение, которое я искал (или что-то в этом роде):
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"