C++pthread成员函数

C++ pthread member function

本文关键字:函数 成员 C++pthread      更新时间:2023-10-16

可能重复:
类的pthread函数

由于pthread_create行的原因,我无法编译以下代码:

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

这条gcc线路:

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

最终使用以下输出进行编译:

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]

显然代码工作不正常,当if (threaded)被引发时,我得到了sementation fault

我知道它与强制转换有关,但我不知道将成员函数传递到pthread_create中的正确形式。有什么建议吗?

尝试将_threaded_run设置为静态。在标题中:

private:
  static void* _threaded_run(void*);

在实施中:

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

然后在创建线程时:

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

正如@ildjarn所建议的,只需制作一个免费函数:

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);

由于函数不依赖于任何特定gtk_functor对象的状态,因此将其作为成员函数是没有意义的。


在一个假设的不同世界中,如果您真的希望在单独的线程中调用对象的成员函数,则需要以某种方式传递对象的对象引用,通常通过参数void指针:

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();
}

事实上,您甚至可能希望将更多上下文信息打包到一些辅助结构中,并将一个指向的void指针传递给线程调用程序函数。