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
int
pthread_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:
- Use
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.