forkOS似乎无法保留线程的本地存储

时间:2014-10-10 13:47:39

标签: multithreading opengl haskell concurrency ghc

我在fork中使用各种GL操作时遇到错误(它们在主线程上工作正常)。例如,createProgram我得到了:

  

用户错误(未知的OpenGL扩展条目glCreateProgram,检查OpenGL 3.1)

当我初始化我的背景(4.3核心)后,我正在调用它。
问题是我在使用forkOS时遇到此错误,但它仍然失败(好像我在一个不知道GL上下文的TLS中)。

发生了什么事?

module Main where
import Graphics.UI.GLUT
import Control.Concurrent
import Control.Monad

main :: IO ()
main = do
    getArgsAndInitialize
    initialDisplayMode $= [RGBMode, DoubleBuffered] 
    initialContextVersion $= (4,3)
    initialContextProfile $= [CoreProfile]
    initialContextFlags $= [DebugContext, ForwardCompatibleContext]
    createWindow "GL Window"

    createProgram -- Works
    forkOS $ void createProgram -- Fails (user error)

    displayCallback $= do
        clearColor $= Color4 0.2 0.2 1 1
        clear [ColorBuffer]
        flush >> swapBuffers

    mainLoop

1 个答案:

答案 0 :(得分:2)

OpenGL上下文绑定到一个线程。基本上它们是TLS结构。 forkOS不会为您自动“结转”您的OpenGL上下文绑定。 forkOS的想法是通过它绑定的Haskell操作保持在与操作系统看到的相同的线程中。 forkIO可以通过Haskell自己的调度程序在线程之间进行混乱操作,这只会使FFI调用的库和API的TLS关联成为一场噩梦。

当GLUT createWindow执行时,它会创建一个窗口一个OpenGL上下文并将其绑定到调用线程。

所以你必须选择:将OpenGL上下文重新绑定到另一个线程。或者您创建另一个上下文,向第一个上下文安装命名空间共享,并将其绑定到另一个线程。