threading this method produces a segfault, why?

早过忘川 提交于 2019-12-13 02:23:03

问题


So im using GLFW and the following method works when called in my main method

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



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

but when i try to run it on a separate thread i get a segfault

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

any ideas? ask if you want any more of the code

Edit: 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);
}

回答1:


Display* d;

You haven't created an object here, just an uninitialised pointer.

d->start();

This calls a member on a nonexistent object. When it tries to access any members in the run() function it just accesses garbage because there is no object.

You probably want to create an object like this:

Display d;
d.start();

Also your start function will terminate the program because you don't join the thread before it is destroyed. You should learn the basics of C++ object lifetime before trying to use threads and pointers like this.

Stop using pointers until you understand the basics. displayThread should be an actual std::thread not just a pointer to some std::thread that goes out of scope.

Then you can just do:

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

Make sure you call displayThread.join() before it is destroyed, e.g in the Display destructor.




回答2:


//make windows context current
glfwMakeContextCurrent(window);

This makes it active on the CURRENT thread. Run this on the thread where you want to render and it should work. Currently it's in the constructor.



来源:https://stackoverflow.com/questions/32933812/threading-this-method-produces-a-segfault-why

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!