C++ pthread成员函数

Hai*_*x64 1 c++ g++ pthreads member-functions

可能重复:
来自类的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个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]
Run Code Online (Sandbox Code Playgroud)

显然代码不能正常工作,我得到sementation faultif (threaded)提升.

我知道它与演员,但我不知道将成员函数传递给pthread_create的正确形式.有什么建议?

Ker*_* SB 5

正如@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);
Run Code Online (Sandbox Code Playgroud)

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


在假设不同的世界里,你真的想一个对象的成员函数在一个单独的线程调用,需要传递的对象的对象引用周围不知何故,通常通过参数空指针:

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();
}
Run Code Online (Sandbox Code Playgroud)

事实上,你甚至可能希望更多的上下文信息打包成一些辅助结构和一个空指针传递的是对线程调用函数.


Lin*_*ios 5

尝试制作_threaded_run静态.在标题中:

private:
  static void* _threaded_run(void*);
Run Code Online (Sandbox Code Playgroud)

并在实施中:

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

然后在创建线程时:

pthread_create(&t_num, NULL, &gtk_functor::_threaded_run, static_cast<void*>(&win));
Run Code Online (Sandbox Code Playgroud)

  • pthreads是一个`C库`.因此它只能理解函数的"C"指针.传递它指向静态方法的指针容易出错.您应该只传递一个已声明为`extern"C"`的函数的地址,或者仅由C编译器而不是C++编译器编译.标准中没有任何内容保证C++函数或静态方法与C函数具有相同的调用约定. (4认同)