围绕函数调用 std::thread() 的工作方式不同

Posted

技术标签:

【中文标题】围绕函数调用 std::thread() 的工作方式不同【英文标题】:Calling std::thread() around a function works differently 【发布时间】:2021-03-19 03:32:55 【问题描述】:

这里的代码有什么原因吗:

int main(int argc, char* argv[])


    Main::Init();
    std::thread worker(Main::Mainloop);
    worker.join();
    Main::Free();

    return 0;

这里的代码应该与这里的代码不同:

int main(int argc, char* argv[])


    Main::Init();
    Main::Mainloop();
    Main::Free();

    return 0;

注意Main 类被定义为单例,代码如下: ma​​in.h

#pragma once

#ifndef MAIN_H
#define MAIN_H


#include "window.h"


#include "mainloop.h"


 

class Main    ///Singleton

public:
    Main(const Main&) = delete;
    Main(Main&&) = delete;
    Main& operator=(const Main&) = delete;
    Main& operator=(Main&&) = delete;



private:
    Main();


    static Main& Get_Instance();


    friend int main(int argc, char* argv[]);


    static void Mainloop();
    static void Init();
    static void Free();


;



#endif // MAIN_H

上面的第一个示例未能初始化我正在用于我的程序的GLFW, GLEW, and ImGui 之一。我试图拆分程序的初始化,但后来我遇到了这个问题。当我进一步挖掘时,我达到了这一点,这实际上没有任何意义,为什么它不应该工作。基本上它要么抛出异常,要么 ImGui 在运行时向我发送许多错误消息:

failed to compile vertex shader!
failed to compile fragment shader!
failed to link shader program! (with GLSL `#version 460`)

然而窗口打开了,我只在运行时通过线程示例得到这些。不是和另一个。

【问题讨论】:

【参考方案1】:

所有这些库都以某种方式与 OpenGL 交互,因此对它们正在执行的线程非常敏感。当前的 OpenGL 上下文是线程特定的;每个线程都有自己的当前上下文,并且一个上下文在任何时候只能在一个线程中是当前的。

创建 GLFW 窗口会创建 OpenGL 上下文。如果您随后切换到另一个线程,除非您告诉 GLFW 使其在该线程中成为当前上下文,否则该上下文在该线程中将不是当前的。

【讨论】:

那么 OpenGL 中的任何渲染都必须在创建上下文的同一线程上? @prtwrt:不一定,但您必须将上下文重新分配给正在执行 OpenGL 命令的线程。见glfwMakeContextCurrent @BDL 所以看来OpenGL的渲染和设置不能是多线程的,就好像你改变了当前的上下文,可能会在另一个线程上渲染中途改变

以上是关于围绕函数调用 std::thread() 的工作方式不同的主要内容,如果未能解决你的问题,请参考以下文章

std::thread 通过引用传递调用复制构造函数

std::thread 按引用传递调用复制构造函数

如何使用 std::thread C++ 生成多个调用相同函数的线程 [关闭]

可连接 std::thread 的析构函数

如何在 Qt 的主事件循环中使用 std::thread?

std::thread 在无限循环中随机时间后锁定