线程化这个方法会产生段错误,为什么?

时间:2015-10-04 13:06:00

标签: c++ multithreading glfw

所以即时使用GLFW,以下方法在我的main方法中调用

void Display::run() {
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */



        /* Swap Buffers And Poll */
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}

但是当我尝试在一个单独的线程上运行它时,我得到一个段错误

std::thread t1(&Display::run, this);

任何想法?询问您是否需要更多代码

编辑: main.cpp中

#include "src/support/Display.h"

int main() {
    Display* d;
    d->start();
    return 0;
}

Display.h

#include <GLFW/glfw3.h>
#include <exception>
#include <thread>


class Display {

private:
    GLFWwindow* window;
    std::thread* displayThread;

    void run();

public:
    Display();
    void start();
    void close();
};

/* Exceptions */
struct GLFWNotInitilizedException : public std::exception
{
    const char * what () const throw ()
    {
        return "ERR: Could Not Initialize GLFW";
    }
};

struct WindowNotCreatedException : public std::exception
{
    const char * what () const throw ()
    {
        return "ERR: Could Not Create Window";
    }
};

Display.cpp

#include "Display.h"

Display::Display() {
    //init glfw
    if (!glfwInit())
        throw GLFWNotInitilizedException();

    //create window and its context
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        throw WindowNotCreatedException();
    }

    //make windows context current
    glfwMakeContextCurrent(window);

    //run(); //this works instead of calling start() which puts run() into a thread

}

/* begins the rendering of the display window contents in seperate thread */
void Display::start() {
    std::thread t1(&Display::run, this);
    displayThread = &t1;
}

/* renders contents of display window */
void Display::run() {
    while (!glfwWindowShouldClose(window)) //seg fault is output here
    {
        /* Render here */



        /* Swap Buffers And Poll */
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}


/* to be used when closing display window */
void Display::close() {
    glfwSetWindowShouldClose(window, true);
    displayThread->join();
    glfwDestroyWindow(window);
}

2 个答案:

答案 0 :(得分:2)

//make windows context current
glfwMakeContextCurrent(window);

这使它在 CURRENT 线程上处于活动状态。在要渲染的线程上运行它,它应该工作。目前它在构造函数中。

答案 1 :(得分:1)

Display* d;

你还没有在这里创建一个对象,只是一个未初始化的指针。

d->start();

这会调用不存在的对象上的成员。当它试图访问run()函数中的任何成员时,它只是访问垃圾,因为没有对象。

您可能想要创建一个这样的对象:

Display d;
d.start();

此外,您的启动功能将终止该程序,因为您不会在销毁之前加入该线程。在尝试使用这样的线程和指针之前,您应该学习C ++对象生存期的基础知识。

在了解基础知识之前,请停止使用指针。 displayThread应该是一个实际的std::thread,而不仅仅是指向超出范围的某些std::thread的指针。

然后你可以这样做:

void Display::start() {
    displayThread = std::thread(&Display::run, this);
}

确保在销毁之前调用displayThread.join(),例如在Display析构函数中。