我可以假设计划在串行队列上运行的块都将在同一个线程上运行吗?
Posted
技术标签:
【中文标题】我可以假设计划在串行队列上运行的块都将在同一个线程上运行吗?【英文标题】: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
?
【问题讨论】:
【参考方案1】: dispatch_queue_create(3) Mac OS X Manual Page队列不绑定到任何特定的 执行线程
无法保证发送到串行队列的所有块都发送到同一个线程。您需要使用主队列进行渲染或使用 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】:不,抱歉,我们无法保证。
【讨论】:
有相关文档吗?以上是关于我可以假设计划在串行队列上运行的块都将在同一个线程上运行吗?的主要内容,如果未能解决你的问题,请参考以下文章