【问题标题】:OpenGL multiple threads, variable handling [closed]OpenGL多线程,变量处理[​​关闭]
【发布时间】:2012-10-10 23:02:47
【问题描述】:

我编写了一个 OpenGL 程序,它以以下方式运行:

Main:
- Initialize SDL
- Create thread which has the OpenGL context:
    - Renderloop
        - Set camera (view) matrix with glUniform.
        - glDrawElements() .... etc.
        - Swapbuffers();
- Main SDL loop handling input events and such.
    - Update camera matrix of type glm::mat4. 

这就是我将相机对象传递给处理 opengl 的类的方式。

Camera *cam = new Camera();
gl.setCam(cam);

在哪里

void setCam(Camera *camera) {
    this->camera = camera;
}

对于在 opengl 上下文线程中进行渲染,会发生这种情况:

glm::mat4 modelView = camera->view * model;
glUniformMatrix4fv(shader->bindUniform("modelView"), 1, GL_FALSE, glm::value_ptr(modelView));

在我的 SDL 和其他东西是句柄的主程序中,然后我重新计算视图矩阵。在我没有使用任何互斥锁的情况下,他的工作正常。这是正确的吗?

另一方面,我通过“上传队列”将对象添加到我的场景中,在这种情况下,我必须在向其添加项目时互斥锁我的上传队列向量(向量类类型),否则程序会崩溃。

总结:我在另一个线程中重新计算我的矩阵,然后在没有任何互斥锁的 opengl 线程中使用它。为什么会这样?

编辑: 我认为我的问题类似于这里提出的问题:

1) Should I lock a variable in one thread if I only need it's value in other threads, and why does it work if I don't?,仅在我的情况下,它更简单,只需更改一个矩阵。

2) Do I need a lock when only a single thread writes to a shared variable?

【问题讨论】:

  • OpenGL 中没有gl.setCam 函数。或者 SDL。在不知道 gl.setCam 做什么或它如何处理其指针参数的情况下,无法回答您的问题。
  • 对不起。用更多细节更新了代码。

标签: c++ multithreading thread-safety


【解决方案1】:

为什么会这样?

谁说的?

多线程代码的经验法则非常简单:如果您的多线程代码可证明是线程安全的,那么默认情况下它就是错误的。

互斥锁和其他同步结构允许您证明您的代码有效。如果没有经过验证的功能,您只是在掷骰子。也许你在那台机器上很幸运。也许如果您重新启动计算机,它将停止工作。如果你打喷嚏,它可能会破裂。

仅仅因为某些事情发生按您的意图运行并不意味着它可以工作。只是你侥幸逃脱,就像一个小偷没有被警察抓住并不意味着他们再试一次就不会抓住他。

如果需要,您可以选择依赖未经验证的线程代码。或者你可以做正确的事而不必担心。


据我了解,这与我在哪里做的行为相同

不,不会的。

在您的第一种情况下,您正在传递一个指向堆栈对象的指针。当范围结束时,该堆栈对象将被销毁。从那时起,任何试图使用该指针的任何事情都会导致错误。

在第二种情况下,您将一个指针传递给一个新分配的堆对象。当销毁该对象时,该对象将被销毁。必须有人负责删除此对象。大概当您将该指针传递给gl.setCam 时,gl 对象将承担在适当的时间销毁它的责任。

这里是标准的 C++ 东西;它与OpenGL,多线程,任何东西都没有关系。这完全是关于所有权的概念;您将堆栈拥有的内存传递给期望声明所有权的函数。你做了一个你无法兑现的承诺。因此,繁荣。

【讨论】:

  • 我知道这一点。这与问题无关。我不应该包含这些信息,因为我现在看到它只会造成混乱。我已经编辑了我的问题,现在只保留了相关信息。
  • 我正在阅读来自 thread 的答案。其中说:1)只有一个线程在写,其他线程都在读。这就是我正在做的事情。我从不更改 opengl 上下文中的相机矩阵,我只是从中读取。
  • 感谢您的回复。我担心互斥锁/解锁在渲染循环中会是一个昂贵的调用。
  • @toeplitz:您不应该在渲染循环期间向渲染系统抛出数据。您应该将数据扔到一个特殊的系统中,该系统将以它想要的速度将数据提供给渲染循环。你的线程同步的东西去那里。拥有可证明的线程同步的最有效方法是最小化线程间通信。将它们全部放在尽可能少的地方。
  • 感谢您的提示。你知道这方面的任何参考资料或例子吗?
【解决方案2】:

为什么会这样?

我不知道,我的水晶球坏了,你没有给我们你的密码。由于 OpenGL 没有相机并且您使用相机类,我认为您可能有一些副本(可能泄漏内存)。

【讨论】:

  • 统一视图矩阵是正在使用的,它是相机类的一部分。我这样计算模型视图矩阵:glm::mat4 modelView = camera->view * model;
  • 在我的帖子中添加了更多详细信息。
猜你喜欢
  • 1970-01-01
  • 2018-06-24
  • 2020-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-07
  • 2019-10-20
  • 1970-01-01
相关资源
最近更新 更多