我在使用线程(使用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”分支上。
答案 0 :(得分:1)
正如hammar所说,添加-threaded到构建选项解决了它。我没有意识到有一个编译器选项用于线程化的东西!
我还会努力清理上面提到的竞争条件:)