我在使用线程(使用 STM)并将其与 GTK 结合时遇到了一些麻烦(http://hackage.haskell.org/package/gtk-0.12.3)。
我有一个无限循环的函数,每 2 秒滴答一次,打印列表的内容,然后清除列表,定义如下
data VirtualHelicopter = VirtualHelicopter { getOrders :: TVar [(Option, Int)] }
run :: VirtualHelicopter -> IO ()
run h = do
forever ( (putStrLn . show =<< (atomRead orders))
>> clearOrders orders
>> milliSleep 2000)
where
orders = getOrders h
atomRead = atomically . readTVar
clearOrders x = atomically $ writeTVar x []
milliSleep = threadDelay . (*) 1000
此外,我有一个 GUI 功能,定义为
runGUI :: VirtualHelicopter -> IO ()
runGUI flyer = do
Gtk.initGUI
~ GUI set up stuff, some key listeners that write to the TVar inside flyer ~
forkIO $ run flyer
Gtk.mainGUI
如果我从 GHCI 内部 forkIO 的“运行”功能,一切正常 - 它每 2 秒滴答一次,打印到控制台并使用传单中的 TVar 添加到队列中的任何内容更新队列。
但是,当我尝试从 GUI 中 forkIO 时,它不再每两秒滴答一次 - 它只是挂起,直到我输入一些输入,然后给出不可靠的输出。
有人知道为什么会这样吗?您可以在https://github.com/tetigi/majom看到整个项目的完整上下文,这是该项目理念的 Haskell 扩展http://procrastineering.blogspot.co.uk/2011/11 /computer-controlling-syma-helicopter.html。线程实现在“threadingForVHeli”分支上。