pthread function from a class
You can't do it the way you've written it because C++ class member functions have a hidden this
parameter passed in. pthread_create()
has no idea what value of this
to use, so if you try to get around the compiler by casting the method to a function pointer of the appropriate type, you'll get a segmetnation fault. You have to use a static class method (which has no this
parameter), or a plain ordinary function to bootstrap the class:
class C
{
public:
void *hello(void)
{
std::cout << "Hello, world!" << std::endl;
return 0;
}
static void *hello_helper(void *context)
{
return ((C *)context)->hello();
}
};
...
C c;
pthread_t t;
pthread_create(&t, NULL, &C::hello_helper, &c);
Calling a class member function from a thread using pthread_create
You can do this via a function that dispatches the work accordingly:
#include <iostream>
#include <pthread.h>
struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}
virtual ~Base() {}
};
struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};
void* thread_adapter(void* obj) {
Base* p = static_cast<Base*>(obj);
p->work();
return nullptr;
}
int main() {
Derived d;
pthread_t thread;
pthread_create(&thread, nullptr, thread_adapter, &d);
pthread_join(thread, nullptr);
}
Live example
pthread_create
accepts a pointer to arbitrary data for the thread function. Pass the address of your object, and use a forwarding function such as the thread_adapter
defined above. Inside the adapter function, you can static_cast
the argument back to a Base*
inside your thread function and invoke the member function as desired.
However, you may want to look into the std::thread library, which supports such operations in a more natural way:
#include <iostream>
#include <thread>
struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}
virtual ~Base() {}
};
struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};
int main() {
Derived d;
std::thread t(&Base::work, d);
t.join();
}
Live example
pass the class method as pthread start function [duplicate]
The 'usual' approach is, to pack the object and all function arguments into a struct, allocate this struct on the heap, pass an instance of this struct to a function with C binding and let that function call the objects member function:
struct wrap {
char * msg;
Foo ins;
wrap( char* m, const Foo& f ) : msg(m), ins(f) {}
};
extern "C" void* call_func( void *f )
{
std::auto_ptr< wrap > w( static_cast< wrap* >( f ) );
w->ins.func(w->msg);
return 0;
}
int main() {
wrap* w = new wrap( "Hi dude", Foo() );
pthread_t pt;
pthread_create( &pt, NULL, call_func, w );
}
How to start pthread inside class constructor on member function of same class?
pthreads uses a C-based API and so it can only use free-standing functions for thread procedures, not non-static class methods. A non-static class method has a hidden this
parameter that pthreads doesn't know about.
However, you can declare threadLoop
as static instead (to remove the this
parameter), and then pass the class's this
pointer to threadLoop
in its user-defined argument.
Also, you need to resize()
your workers
container, not reserve()
it. reserve()
preallocates the container's internal memory, but it does not add new elements (only the capacity()
changes, not the size()
). Using operator[]
to access elements that have not actually been added to the container is undefined behavior.
Try this instead:
class ThreadPool
{
private:
std::vector<pthread_t> workers;
static void* threadLoop (void *arg);
public:
ThreadPool(int num_workers);
...
};
ThreadPool::ThreadPool(int num_workers)
{
workers.resize(num_workers);
for (int i = 0; i < num_workers; i++) {
pthread_create(&workers[i], NULL, threadLoop, this);
}
}
void* ThreadPool:threadLoop (void *arg)
{
ThreadPool *pThis = (ThreadPool*) arg;
// use pThis as needed...
}
Technically speaking, using a non-static class method as a free-standing function is also undefined behavior, but it works fine in most compilers, and there are plenty of libraries that are designed around that functionality. If in doubt, you can always define an actual free-standing function, and make it a friend
of your class if it needs to access non-public members.
Pthread_create call function in class [duplicate]
I suggest to you use stl container instead of C arrays.
The Customer::run is static function so you not need pass this function like this:
status = pthread_create (..., Customers[index].run, ...);
For passing static function to pthread you need pass pointer to static function:
status = pthread_create(..., &Customers::run, ...);
Ok we pass function but also I guess you wish to pass concrete Customer object to thread
status = pthread_create(..., &Customers::run, (void *)Customers[index]);
End-version of the code will look like
void *Customer::run(void *arg)
{
Customer *this_ = (Customer *)arg;
// Do something
}
std::list<pthread_t> pthreads(50);
std::list<Customer *> Customers(50);
for (size_t i = 0; i < pthreads.size(); ++i)
{
Customers[i] = new Customer();
status = pthread_create(&pthreads[i], &Customer::run, (void *)Customers[i]);
...
}
for (size_t i = 0; i < pthreads.size(); ++i)
{
pthread_join(pthreads[i]); // block until thread end
delete Customers[i]; // free mem
}
C++ pthread member function [duplicate]
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, >k_functor::_threaded_run, static_cast<void*>(&win));
Pthread for C++ class functions which uses refrence to class object
wrapper1Fun
expects to be passed a pointer to a Wrapper
, and wrapper2Fun
expects to be passed a pointer to a Wraper2
. But you're actually passing a pointer to a ThreadWrapper
to each, which is a completely different type, so it goes wrong.
The use of void *
and casts prevents the compiler from pointing out your type error. I would suggest using a type safe C++ threading library rather than raw pthread
. Boost has one, as does the standard library from C++11.
Also your use of auto_ptr
is questionable at best. It's deprecated, easy to get wrong, and a poor way of expressing ownership - prefer unique_ptr
or shared_ptr
.
Here you construct two auto_ptr
values owning the same pointer, so it will be freed twice, which is undefined behaviour.
In any case there's no obvious reason to put any of these objects on the heap. If you do, you need to decide where the ownership of the memory resides.
pthread member function of a class with arguments
I think a better solution for using things such as pthread(which take c callbacks) is to create a wrapper function so that you can use much easier to manipulate boost::functions instead. This is similar to Using boost::bind() across C code, will it work?.
Then you could solve your problem simply with boost::bind
class myClass
{
void atom(myStruct *data); // void return type to keep it similar to other code
// You could change it to a void* return type, but then you would need to change the boost::function declarations
};
boost::function<void(void)> function = boost::bind(&myClass::atom,&myClassInstance,&myStructInstance); //bind your function
boost::function<void(void)>* functionCopy = new boost::function<void(void)> (function); //create a copy on the heap
pthread_t id;
pthread_create(&id,NULL,&functionWrapper,functionCopy);
The wrapper function would look like this.
void functionWrapper(void* data)
{
boost::function<void(void)> *func = (boost::function<void(void)>* ) (data);
(*func)();
delete(func);
}
While this method may be more work than manually passing in data, it is much more extendable, making it easy to bind anything and pass it to start your thread.
EDIT
One last note: myClassInstance and myStructInstance should be on the heap. If they are on the stack they could get deleted before your thread starts.
How to multithreading a class member function with pthreads?
This should do the job: (After making the function extensionStep
static)
rc = pthread_create(&threads[i], NULL, &(SVAnchor::extensionStep), &td[i]);
Or you can create a wrapper function like this:
struct Argument {
SVAnchor* ptr;
int* tid;
}
static void *extensionStepWrapper(void *arg)
{
return (((Argument*)arg)->ptr)->extensionStep(((Argument*)arg)->tid);
}
And use the wrapper:
Argument arg;
arg.ptr = &(class_variable_name); // Use appropriate name (whatever you variable name is for the object of the class SVAnchor)
arg.tid = &(td[i]);
rc = pthread_create(&threads[i], NULL, &(SVAnchor::extensionStepWrapper), &arg);
Note that if you're calling this from inside another member function, you may do this instead:
arg.ptr = this;
You can also create a method in the class to start the thread:
bool StartThread(int* tid){
return (pthread_create(&_thread, NULL, extensionStep, tid) == 0);
}
You might also need to pass the thread as argument of StartThread() function.
Related Topics
Unresolved External Symbol on Static Class Members
Singleton: How Should It Be Used
Is Meyers' Implementation of the Singleton Pattern Thread Safe
How to Concatenate a Std::String and an Int
Generating Random Integer from a Range
How to Convert a Number to String and Vice Versa in C++
Delete VS Delete[] Operators in C++
How to Find Out If an Item Is Present in a Std::Vector
Generate Random Numbers Uniformly Over an Entire Range
Is Local Static Variable Initialization Thread-Safe in C++11
Order of Evaluation of Arguments Using Std::Cout
Why Don't I Get a Segmentation Fault When I Write Beyond the End of an Array
Why Is Address of Char Data Not Displayed