如何从分叉线程安全地使用WebKitGTK?

Art*_*yom 8 gtk multithreading haskell webkitgtk

我正在尝试使用GTK3和WebKit在Haskell中创建一个简单的应用程序.此代码创建并显示一个包含WebView内部的窗口,每次按下一个键时都会显示一个随机数.

import           Control.Monad.Trans (lift)
import           Control.Concurrent (forkOS)
import           System.Random (randomIO)
import           Graphics.UI.Gtk                   -- gtk3
import           Graphics.UI.Gtk.WebKit.WebView    -- webkitgtk3


main = forkOS $ do

  -- Init GTK.
  initGUI

  -- Create a window which would finish the GTK loop
  -- after being closed.
  window <- windowNew
  window `after` objectDestroy $
    mainQuit

  -- Create a WebView inside.
  webView <- webViewNew
  set window [containerChild := webView]

  -- Make the WebView display a random number on key press.
  webView `on` keyReleaseEvent $ lift $ do
    x <- randomIO :: IO Int
    webViewLoadString webView (show x) Nothing Nothing ""
    return True

  -- Run GTK.
  widgetShowAll window
  mainGUI
Run Code Online (Sandbox Code Playgroud)

当我在GHCi(7.8.3)中运行它时,它工作正常.然而,当我再次运行而不退出GHCi时,WebView从未显示任何东西 - 只是纯白色区域.这很令人沮丧,因为我喜欢修改GHCi中的代码.

当然,如果我不使用forkOS并在主线程中运行整个事情,一切正常.这种限制的原因是什么(我认为所有GTK函数都被认为是"主要"线程initGUI被称为),并且可以以某种方式克服它?

Que*_*les 1

如果它像 python (我不知道 haskell)一样工作,你应该gtk main loopmain thread.

在您的第二个线程中,使用回调调用g_idle_addtransport data between来对 gtk 进行更改,以及您的second thread, 和gtk. 您应该先启动非主线程gtk main,这样它就不会被阻塞。

我确信 haskell 中有一个绑定g_idle_add。还有 g_timeout_add 也适用于此。

这一切都与 gtk 不是线程安全有关。