【问题标题】:Can I assume that blocks scheduled to run on a serial queue will all run on the same thread?我可以假设计划在串行队列上运行的块都将在同一个线程上运行吗?
【发布时间】:2011-03-27 00:38:27
【问题描述】:

我正在为 Mac OS 10.6 构建一个将使用 OpenGL 的应用程序。我想将渲染离岸到辅助调度队列(而不是主线程)。

据我了解,我需要使用线程本地 OpenGL 上下文来完成我的图形工作。我的计划是在我的第一个块中获取对它的引用,然后一遍又一遍地重用同一个实例。

但是,调度队列和线程并不相同,Xcode 4 的调试器显示一个队列可以使用多个线程。因此,我不确定我正在做的事情是否安全(尽管我相信只有并行队列可以使用多个线程)。

是否可以保证发送到串行队列的所有块都发送到同一个线程?我是否应该获取当前的 OpenGL 上下文并在每一帧将其分配给我的NSOpenGLView

【问题讨论】:

    标签: multithreading cocoa opengl grand-central-dispatch


    【解决方案1】:

    队列不绑定到任何特定的 执行线程

    无法保证发送到串行队列的所有块都发送到同一个线程。您需要使用主队列进行渲染或使用 NSThread 或 pthread 作为主队列在具有 GL 上下文的线程上实现对块的排队。

    【讨论】:

    • 实际上,我发现OpenGL上下文也没有绑定到任何特定的线程,所以这并不重要。不过,我一直在寻找那份文档。谢谢。
    【解决方案2】:

    您不需要为每个线程使用单独的 OpenGL 上下文。但是 OpenGL 上下文一次只能在一个线程中处于活动状态。因此,您可以做的是在进入工作集时使上下文处于活动状态,并在离开时将其停用。

    但是,OpenGL 的多线程使用通常会降低性能。无论如何,OpenGL API 调用方可以并行化的东西很少,因为操作的顺序非常重要。然而,GPU 将完美地并行化所有操作。

    所以我建议将所有 OpenGL 操作保留在一个线程中,并将工作队列用于 I/O、用户交互、声音、模拟等。

    【讨论】:

    • 我为 OpenGL 使用单独的工作队列,因为调度计时器非常适合触发渲染:它们非常精确、轻量级(我的机器上 CPU 开销约为 0.4%),并且事件被合并(如果渲染滞后,这是一件好事);它并不是真正用于并行化的东西。我昨天还读到,我不需要每个线程一个上下文,而是我应该一次在一个线程上使用一个上下文,所以我所做的至少是安全的。
    【解决方案3】:

    这里有一些关于使用 GCD 的 OpenGL 的更具体信息:

    http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/ConcurrencyandOpenGLES/ConcurrencyandOpenGLES.html

    GCD 和 NSOperationQueue 对象可以在一个线程上执行你的任务 他们的选择。他们可能会专门为该任务创建一个线程, 或者他们可能会重用现有线程。但无论哪种情况,你都不能 保证哪个线程执行任务。对于 OpenGL ES 应用程序,这意味着:

    • 每个任务必须在执行任何 OpenGL ES 之前设置上下文 命令。
    • 您的应用程序必须确保访问 不允许同时执行相同的上下文。
    • 每个任务都应该 退出前清除上下文。

    【讨论】:

      【解决方案4】:

      不,抱歉,我们无法保证。

      【讨论】:

      • 有相关文档吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-03
      • 1970-01-01
      • 2012-08-06
      相关资源
      最近更新 更多