2017-09-26 31 views
0

我有一个应用程序呈现到一个线程中的纹理,另一个线程从这个纹理读取数据。两个线程之间的上下文是共享的。在阅读线程将读取部分数据的情况下,是否有可能出现竞争条件?是否可以在写入时渲染纹理?

+3

是的,这基本上是数据竞赛的完美设置。 –

+0

@DietrichEpp我在网上读到,当有东西从两个不同的线程写入上下文时,可能会发生问题,但是我找不到任何说明写入的影响,只能从另一个读取。 – Kyle

回答

1

the OpenGL 4.6 core spec从,第5.3.1节:

对象T的内容被认为已经改变一次这样的命令,如第5.3节描述的已完成。可以通过调用Finish或调用FenceSync并在关联的同步对象上执行WaitSync命令来确定完成命令1。

  1. 两个或多个线程被写入到存储器中的相同位置,和

  2. 至少线程之一是:

通常,数据竞争时发生书写和

  • 线程之间没有同步。

  • 你可以看到,在OpenGL中,你需要或者等待Finish()WaitSync()返回知道你的操作是同步的。有额外的规则,注释部分5.3.3:

    规则4如果对象T的内容在比当前上下文之外的上下文被改变时,T必须被附接或重新连接到至少当前上下文中的一个绑定点或当前绑定的容器对象C的至少一个连接点,以保证T的新内容在当前上下文中可见。

    所以,如果你写在线程A引起的纹理,在线程B读取它,你必须做到以下几点:

    1. 创建一个同步对象。

    2. 一旦写入完成,就从线程A发出同步对象的信号。

    3. 等待在线程B的同步对象

    4. 重新绑定在线程B.纹理

    这些步骤都完成之后,你可以从线程B.纹理读取

    注:您可能会发现与数据种族代码,如果你对测试它将会“正常工作”你自己的电脑。这并不奇怪......有时候它会起作用,有时候它不会。也许它会一直在你的电脑上工作,并炸毁别人的电脑。更好的做法是通过线程同步来实现,只是测试不够好。

    1

    可能,绝对是。

    虽然没有必要。在GLsync和glFinish中有很好的同步原始码,你没有理由不使用它们。

    究竟是什么影响来自数据竞赛是未指定的。您最终可能会读取一半纹理,您可能会在驱动程序中调用致命错误,或者它可能会停止。