-1

我编写了一个 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)如果我只需要它在其他线程中的值,我是否应该将变量锁定在一个线程中,如果我不这样做,为什么它会起作用?,仅在我的情况下,仅更改一个矩阵就更加简单。

2)当只有一个线程写入共享变量时,我需要锁吗?

4

2 回答 2

2

为什么这行得通?

谁说它是?

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

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

仅仅因为某些事情发生如你所愿并不意味着它有效。只是你逃脱了它,就像一个小偷没有被警察抓住并不意味着他们再试一次就不会抓住他。

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


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

不,不会的。

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

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

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

于 2012-10-11T01:47:31.113 回答
0

为什么这行得通?

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

于 2012-10-11T00:40:14.110 回答