Passing normal data to pthread void *
The pthread functions take a void * argument. How can a plain struct, not a pointer be sent in?
I want to send in a non pointer struct to one pthread function.
Also I want to send a pointer to the void * function, how is this done? c开发者_运维百科an any pointer be sent in to the void * function?
Not possible; you have to send a pointer. However, a void *
can point to anything. If your struct variable is called foo
, you can simply pass it as (void *) &foo
, and inside the function, you can cast it back into e.g. a struct Foo
with struct Foo * fooPtr = (struct Foo *) param;
or struct Foo foo = *((struct Foo *) param);
.
Edit: As @forsvarir mentioned in the comment, foo
must not be a local variable (unless the invoking function waits for the thread to complete). See @Gavin Lock's post.
Based on your comments you need to do something like this...
In your main code:
void PassSomeStuff(struct TheStruct myStruct) {
struct TheStruct *pStruct = malloc(sizeof(struct TheStruct));
memcpy(pStruct, &myStruct, sizeof(struct TheStruct));
/* Start the watchdog thread passing in the structure */
pthread_create(/* other args */, &myWatchDogThreadFunc, pStruct); */
}
In your watchdog thread:
void *myWatchDogThreadFunc(void *pArgs) {
struct TheStruct *pStruct = (struct TheStruct *)pArgs;
/* use the struct */
/* Pass Ownership to the navigation thread*/
/* Start the navigation thread passing in the structure */
pthread_create(/* other args */, &myNavigationThreadFunc, pStruct);
}
In your navigation thread:
void *myNavigationThreadFunc(void *pArgs) {
struct TheStruct *pStruct = (struct TheStruct *)pArgs;
/* use the struct */
/* cleanup */
free(pStruct); /* or pass it to somebody else... */
}
You can't just do:
void PassSomeStuff(struct TheStruct myStruct) {
pthread_create(/* other args */, &myStruct);
}
Because myStruct
will get cleaned up... when PassSomeStuff
returns. Taking the address (getting a pointer to it), doesn't copy the object.
Note:
- ANY of your threads can clean up the structure by calling free, as long as you're sure that ALL of the threads are finished with it.
- ALL of the threads (main, watchdog, navigation) are refering to the same instance of the structure (so if they're changing its contents you may need to protect it with locking). If this isn't the desired effect, then you would need to create (malloc) a new copy of the structure at each step, so that each thread has it's own copy of the values.
As already mentioned, you have to pass a pointer. Think of void* as an untyped pointer, so you have to cast it back to the correct type inside your thread function. (see Aasmund's answer)
As forsvarir mentions, you HAVE to make sure that the pointed-to struct is not destroyed before the thread uses it - safest way to do this is to new the struct on the heap and pass its address and ownership to the thread function.
What I mean by "passing ownership" is that the function that news the struct must not delete it, and the thread function must delete the struct once it is done with it.
This isn't a complete answer, but rather an alternative solution to the warnings others have offered about making sure the structure still exists when the new thread gets it. Certainly you can use malloc
to obtain it, and give the new thread the responsibility for free
ing it. In many ways this seems like the simplest and cheapest way (no synchronization required), but the synchronization is actually hidden inside malloc
and free
, and could be mildly expensive, especially since most thread-oriented allocators (ptmalloc and tcmalloc for example) incur additional costs when the thread freeing the memory is not the same as the thread that allocated it.
An different approach you can use is to put a pthread barrier inside your init structure, and wait on it:
pthread_barrier_init(&init_struct.barrier, 0, 2);
pthread_create(&td, 0, start_func, &init_struct);
pthread_barrier_wait(&init_struct.barrier);
And have the thread start function also call pthread_barrier_wait(arg->barrier);
after copying the struct to its own automatic storage.
精彩评论