C++ pthread member function [duplicate]

为君一笑 提交于 2019-12-24 10:24:51

问题


Possible Duplicate:
pthread Function from a Class

I have this code that I can't get to compile because of the pthread_create line:

void* gtk_functor::_threaded_run(void* win)
{
    Gtk::Window* w = static_cast<Gtk::Window*>(win);
    Gtk::Main::run(*w);
    delete w;
}

void gtk_functor::operator ()(Gtk::Window& win, bool threaded)
{
    if (threaded)
    {
        pthread_t t_num;
        pthread_create(&t_num, NULL, (void* (*)(void*))&gtk_functor::_threaded_run, static_cast<void*>(&win));
    }
    else
    {
        Gtk::Main::run(win);
    }
}

This gcc line:

g++ -o main 'pkg-config --cflags --libs sqlite3 gtkmm-3.0' -lpthread main.cpp

does in the end compile with this output:

code/ui.cpp: In member function 'void ui::gtk_functor::operator()(Gtk::Window&, bool)':
code/ui.cpp:45:65: warning: converting from 'void* (ui::gtk_functor::*)(void*)' to 'void* (*)(void*)' [-Wpmf-conversions]

and apparently the code doesn't work correctly, I get sementation fault when the if (threaded) is raised.

I know its with the cast, but I don't know the correct form of passing a member function into pthread_create. Any suggestions?


回答1:


Try making _threaded_run static. In the header:

private:
  static void* _threaded_run(void*);

And in the implementation:

void* gtk_functor::_threaded_run(void* win) {
  Gtk::Window* w = static_cast<Gtk::Window*>(win);
  Gtk::Main::run(*w);
  delete w;
}

Then when creating the thread:

pthread_create(&t_num, NULL, &gtk_functor::_threaded_run, static_cast<void*>(&win));



回答2:


As @ildjarn suggests, just make a free function:

void * threaded_run(void * win)
{
    Gtk::Window * const w = static_cast<Gtk::Window*>(win);
    Gtk::Main::run(*w);
    delete w;
}

// ...

pthread_create(&t_num, NULL, threaded_run, &win);

Since the function does not depend on the state of any particular gtk_functor object, there is no point in making it a member function.


In a hypothetical different world where you really would want an object's member function to be called in a separate thread, you need to pass the object reference for the object around somehow, usually via the argument void pointer:

struct Foo
{
    void * run() { /* ... use state ... */ }

    /* ... state ... */
};

Foo x;
pthread_t pt;

// start a new execution context with x.run():
pthread_create(&pt, NULL, FooInvoker, &x);

extern "C" void * FooInvoker(void * p)
{
    return static_cast<Foo*>(p)->run();
}

In fact, you may even wish to package up more contextual information into some auxiliary structure and pass a void pointer to that to the thread invoker function.



来源:https://stackoverflow.com/questions/11528684/c-pthread-member-function

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