主线程和其他线程之间有什么区别?

时间:2013-01-29 23:17:15

标签: c multithreading opengl glfw

GLFW FAQ上,第2.9项说明:

  

[...] 强烈建议所有OpenGL和GLFW调用   (线程管理和同步调用除外)由   主线程,这应该不是一个大问题,因为只有一个   窗口是支持的。这种方法也与未来兼容   GLFW的方向。

重点是我的。

那么,主线程与其他线程有什么区别?

3 个答案:

答案 0 :(得分:4)

问题涉及旧的GLFW API和常见问题解答,请参阅updated GLFW FAQGLFW thread safety documentation

仍然存在一些约束,并且必须从主线程进行许多GLFW调用。主线程和其他线程之间的区别取决于GLFW处理的窗口创建,事件等的平台特定行为。有关详细信息,请see this post on the official GLFW forum

创建OpenGL窗口后,可以在另一个线程上使上下文成为当前状态,并且可以从该线程进行OpenGL调用。

答案 1 :(得分:3)

声明

  

“是......线程安全吗?不。但是,OpenGL也不行。”

错了。 OpenGL当然是线程安全的。

这是交易:对于每个线程,一个或没有OpenGL上下文可以绑定到drawable(当前的)。 OpenGL调用对在调用的线程中处于活动状态的上下文进行操作。完全可以在线程之间传输OpenGL上下文。为此,首先要转移的上下文必须是未绑定的,然后它可以在另一个线程中反弹。

每个OpenGL上下文管理自己的一组状态变量和对象(纹理,缓冲区)。然而,上下文可以“纠缠”,即共享它们的对象空间。国家仍然是个人。

单个drawable(窗口,PBuffer)可以具有来自绑定到的不同线程的多个上下文。如果来自不同线程的上下文绘制到相同的drawable,则会出现竞争条件并且结果未定义。然而,在深度测试绘图的情况下,结果应该是合理的。然而,同时绘制单个drawable会严重影响性能,因此最好避免使用。

多线程中多个OpenGL上下文的主要用途是共享其对象,以便一个线程可以加载和更新其他上下文的数据。将帮助器上下文绑定到屏幕外或隐藏的drawable是有意义的,以防止发生竞争条件。

线程之间没有技术差异。从编程的角度来看,每个线程将具有稍微不同的语义,这是由运行的程序强加的,而不是由系统架构强加的。在大多数OpenGL应用程序的情况下,传统的语义是,主线程将创建窗口,绘制用户可见的所有元素(包括OpenGL操作)并收集用户输入。从主线程启动的线程是工作线程,没有直接的用户交互。然而,这个任务分配纯粹是选择,因为它结果很好。但是使用不同的方案是完全可能的,有时是可取的。就像已经说过的那样,程序中的线程没有技术差异。所有主题都是一个过程中的平等权利公民。

答案 2 :(得分:1)

文档的措辞可能略有误导。更好的措辞是:

  

强烈建议所有OpenGL和GLFW调用(线程管理和同步调用除外)都来自单个线程,最好是调用glfwInitglfwOpenWindow < / strong>,这不应该是一个大问题,因为只支持一个窗口。这种方法也与GLFW的未来发展方向兼容。

原因是OpenGL的上下文具有“当前线程”的概念,这是可以在给定时间合法修改或使用该上下文的一个线程。上下文最初属于创建它的线程。你可以通过调用wglMakeCurrentglxMakeCurrent使其在某个其他线程中成为“当前”,这与GLFW不同,不可移植(但GLFW可能有一个包装器,我不确定)。

当然很可能有几个独立的上下文,并且可以通过在使用它之前在每个线程中使相同的上下文变为当前来从多个线程访问相同的上下文。最后,可以在多个共享状态的线程中有多个上下文 但是,这些选项都不是常规情况,因为它涉及不可忽略的同步开销或不适合OpenGL的常见用法。除了“一个线程,一个上下文”以外,除了极少数例外情况之外的任何其他事情都没有提供任何优势,但却带来了不必要的复杂性。

因此,常规用例只有一个上下文正好由一个线程使用,并且可选地有一些工作者三个有助于将数据混洗到映射缓冲区中。

至于“主线程”与“任何线程”,没有区别。主线程只是 incidentially 在大多数情况下初始化GLFW(以及OpenGL)的那个。