0

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

4

1 回答 1

1

正如 hammar 所说,将 -thread 添加到构建选项中解决了它。我没有意识到线程有一个编译器选项!

我还将努力清除提到的比赛条件:)

于 2012-11-20T13:44:51.827 回答