问题
I have almost completed an homework assignment where I am required to use pthreads. I have figured out the pthreads. The only problem I have left is figuring out how to pass multiple arguments to threads through pthread_create().
I need to pass two chars to the thread. I have to cast them to (*void) to use with pthread_create(). I can pass them, but I can't figure out how to get the values from *parameter in the function.
void *my_function(void *parameter) {
/* ATTEMPT 1 - DOESN'T WORK */
//char* arguments[2];
//arguments = (char * [2]) parameter;
/*Error message:
error: ISO C++ forbids casting to an array type char* [2] [-fpermissive]
error: incompatible types in assignment of char** to char*[2]
*/
/* ATTEMPT 2 - DOESN'T WORK */
//char *my_data = (char *)parameter;
//my_data is blank when I try to use cout to check it's values
/* What I need to do is get those two chars from the array and print them out as part of this thread function */
pthread_exit(NULL);
}
int main(int argc, char **argv) {
char duration = '5'; //in reality, this value is taken from argv but I am leaving that out for brevity
pthread_t threads[3];
for(int i=0; i < 3; i++){
char thread_args[2] = {i, duration};
//create thread with arguments passed in
int results = pthread_create(&threads[i], NULL, my_function, (void *) &thread_args);
//testing for pthread error
if (results){
printf("ERROR; return code from pthread_create() is %d\n", results);
exit(-1);
}
}
/* Wait for all threads to complete */
for (int j=0; j < num_threads; j++) { // https://computing.llnl.gov/tutorials/pthreads/
pthread_join(threads[j], NULL);
}
/* some information prints here that is unrelated to my problem (the date, time, etc) */
pthread_exit(NULL);
}
I was able to pass one value through with no problem. Any suggestions?
The closest existing question I could find was this but I still am having no luck: Converting from void* to char ** in C
Thank you!
回答1:
Note that within this loop:
for(int i=0; i < 3; i++){
char thread_args[2] = {i, duration};
int results = pthread_create(&threads[i], NULL, my_function, (void *)
...
}
thread_args
is a local array with automatic storage duration, lifetime of which is tied to each iteration so there is a chance that the memory where you store these arguments might be freed before the thread will access it, which would lead to undefined behavior in that case.
Much better approach would be to create a structure, that you would use to pass the data to this thread:
typedef struct {
char duration;
int num;
} ThreadData;
Then your code could look like this:
void *my_function(void *parameter) {
// retrieve and print the thread data:
ThreadData* td = (ThreadData*) parameter;
printf("num = %d, duration = %c\n", td->num, td->duration);
delete td;
return NULL;
}
int main(int argc, char **argv) {
char duration = '5';
pthread_t threads[3];
for (int i = 0; i < 3; i++) {
// create structure that will be passed to thread:
ThreadData* td = new ThreadData;
td->duration = duration;
td->num = i;
//create thread with arguments passed in:
int ret = pthread_create(&threads[i], NULL, my_function, (void *) td);
//testing for pthread error:
if (ret) {
printf("ERROR; return code from pthread_create() is %d\n", ret);
exit(-1);
}
}
// wait for all threads to complete:
for (int i = 0; i < 3; i++) {
pthread_join(threads[i], NULL);
}
exit(0);
}
Also note that to end thread's execution it is better to use return
than pthread_exit
since with return
it is guaranteed that variables within thread's routine will be destroyed and stack will be unwound. For more information see return() versus pthread_exit() in pthread start functions
来源:https://stackoverflow.com/questions/15351002/un-casting-from-void-and-de-referencing-to-char-array