I have the following code where I create threads based on the for loop below, the 3rd argument in pthread takes a void* ()(void) and I am giving it a string arg. The problem is that every thread has it's own method i.e thread 0 has its method thread0(). I want to be able to set the method based on the t of the for loop without getting the following error:
main2.cpp:40:51: error: cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘void* (*)(void*)’ for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’ err = pthread_create(&threads[t], &attr,method, &t);
for(t = 0; t <5; t++){;
printf("Creating thread %d\n",t);
std::string method = "thread"+t;
err = pthread_create(&threads[t], &attr,method, &t);
if(err != 0) exit(-1);
}
The error message is pretty clear about the function pointer, that you can't translate c++ symbols to strings or vice versa.
Here's the signature of pthread_create() as given in the documentation:
SYNOPSIS
intpthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
You can do the following:
typedef void* (*start_routine_t)(void*);
void* foo_0(void*) { return nullptr; }
void* foo_1(void*) { return nullptr; }
void* foo_2(void*) { return nullptr; }
void* foo_3(void*) { return nullptr; }
void* foo_4(void*) { return nullptr; }
constexpr std::map<std::string,start_routine_t> thread_funcs {
{ "thread_0" , foo_0 } ,
{ "thread_1" , foo_1 } ,
{ "thread_2" , foo_2 } ,
{ "thread_3" , foo_3 } ,
{ "thread_4" , foo_4 } ,
};
pthread_t threads[5];
// ....
for(t = 0; t <5; t++){;
printf("Creating thread %d\n",t);
std::ostringstream method;
method << "thread_" <<t;
err = pthread_create(&threads[t], &attr,method, &thread_funcs[method.str()],nullptr);
if(err != 0) exit(-1);
}
Or the more straightforward way without using strings at all:
start_routine_t thread_funcs[5] = { foo_0, foo_1, foo_2, foo_3, foo_4 };
pthread_t threads[5];
// ...
for(t = 0; t <5; t++){
printf("Creating thread %d\n",t);
err = pthread_create(&threads[t], &attr,method, thread_funcs[t], nullptr);
if(err != 0) exit(-1);
}
As you also asked for c++-11 facilities:
std::thread instead of the pthread-API directly at all. If your target environment supports pthreads properly, you usually can use the std::thread ABI.Use lambda functions to refer to specific routines on the fly:
std::vector<std::thread> threads(5);
for(t = 0; t <5; t++){
printf("Creating thread %d\n",t);
auto thread_func = [t]() {
switch(t) {
case 0: foo_0(); break;
case 1: foo_1(); break;
case 2: foo_2(); break;
case 3: foo_3(); break;
case 4: foo_4(); break;
}
};
threads[t] = std::thread(thread_func);
}
The above code example probably isn't the best (most efficient), but demonstrates how to map function calls on the fly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With