我有一个应用程序,它在一个线程中呈现一个纹理,另一个线程从该纹理中读取数据。两个线程之间的上下文是共享的。是否有可能在读取线程读取部分数据的情况下发生竞争条件?
答案 0 :(得分:1)
可能,绝对是。
但这绝不是必要的。 GLsync和glFinish中有精细的同步原语,你没有理由不使用它们。
确切地说,来自数据竞赛的影响是未指定的。您最终可能会读取一半纹理,您可能会在驱动程序中调用致命错误,或者它可能会停止。
答案 1 :(得分:1)
来自the OpenGL 4.6 core spec,第5.3.1节:
一旦完成了5.3节中描述的命令,就认为对象T的内容已经改变。可以通过调用
Finish
,或通过调用FenceSync
并在关联的同步对象上执行WaitSync
命令来确定命令1的完成。
通常,数据竞赛在以下情况发生:
两个或多个线程正在写入内存中的相同位置,
至少有一个主题是写作,
线程之间没有同步。
您可以看到,在OpenGL中,您需要等待Finish()
或WaitSync()
返回才能知道您的操作已同步。还有其他规则,请注意第5.3.3节:
规则4 如果在当前上下文以外的上下文中更改了对象T的内容,则必须将T附加或重新附加到当前上下文中的至少一个绑定点,或者当前绑定的容器对象C的至少一个附着点,以保证T的新内容在当前上下文中可见。
因此,如果您在线程A中写入纹理,并在线程B中读取它,则必须执行以下操作:
创建同步对象。
写完后,从线程A发出同步对象的信号。
等待主题B中的同步对象。
在线程B中重新绑定纹理。
完成这些步骤后,您可以从线程B中的纹理中读取。
注意:如果您在自己的计算机上进行测试,您可能会发现带有数据竞争的代码将“正常运行”。这并不奇怪......有时它会起作用,有时却不会。也许它会一直在您的计算机上运行并炸毁其他人的计算机。最好通过线程同步来解决问题,只是测试不够好。