C ++ pthread member function

Possible duplicate:
Pthread function from class

I have this code that I cannot compile due to 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 is:

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

does a compilation at the end 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 is not working correctly, I get a sementation fault when if (threaded) goes up.

I know it with cast, but I don't know the correct form for passing a member function to pthread_create. Any suggestions?

+1
c ++ pthreads g ++ member-functions
Jul 17 '12 at 18:33
source share
2 answers

Try to make _threaded_run static. In the title:

 private: static void* _threaded_run(void*); 

And in 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 stream:

 pthread_create(&t_num, NULL, &gtk_functor::_threaded_run, static_cast<void*>(&win)); 
+5
Jul 17 2018-12-18T00:
source share

As @ildjarn suggests, just create 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 is independent of the state of any particular gtk_functor object, it makes no sense to make it a member function.




In a hypothetical other world, where you really want the member function of an object to be called in a separate thread, you need to somehow pass an object reference to the object, usually using the 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 might even want to pack more contextual information into some kind of auxiliary structure and pass a void pointer to this function in the stream call function.

+5
Jul 17 '12 at 18:37
source share



All Articles