Haskell Gtk:mainGUI函数阻塞其他线程

时间:2012-11-20 12:09:15

标签: haskell

我在使用线程(使用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”分支上。

1 个答案:

答案 0 :(得分:1)

正如hammar所说,添加-threaded到构建选项解决了它。我没有意识到有一个编译器选项用于线程化的东西!

我还会努力清理上面提到的竞争条件:)