What's the proper way to pass an array to pthread_create? Everywhere I am seeing is (void*)myArray) why is it so? why I have to put void*? Array name is not enough as we do in other languages? And as a function argument why void *add_first_quat(void *a) why we are putting void *?
5 Answers
(void*)myArray)why is it so? why I have to putvoid*? Array name is not enough as we do in other languages?
It's not necessary to cast an array when passing to a thread function. It's probably due to old habits or lack of understanding that void * is compatible with any other data pointer. The cast is redundant at best and could lead to errors at worst.
This is the correct way to pass an array:
pthread_create(&thrd_id, 0, thread_func, array);
as a function argument why
void *add_first_quat(void *a)why we are puttingvoid *?
Because that's what the thread function of pthreads library expects. The reason is that it allows you to pass any data pointer to the thread function (aka "generic" pointer type). Imagine you have 3 threads (same thread function) acting on different types of "struct" data.
4 Comments
void * Will my all functions called be pthread_create will have this return type? And can I pass more arguments to my function that is being called in pthread_createvoid*) of thread function that pthreads library expects. You can't pass more arguments. But you can use a struct with all your arguments and pass the struct variable to thread function. E.g.: struct args { int a; char c; }arg; arg.a = 1; arg.c = 'c'; pthread_create(&thrd_id, 0, thread_func, &arg);*(int*(var)) and (int*)a ?a is. If a is of type void * passed to thread function and it was originally (at caller) an int* then (int*)a simply casts it to an int* (int pointer). *(int*(a) casts it to int* and dereferences to get the int value pointer to by a.This is because you can only have one argument in a function that is used by pthread, as specified by the fourth argument of the function pthread_create, as we can from the manual pages of pthread_create:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
This argument has to be as general as it can get, as you can give different arguments each time you use that function. Void pointers are actually pointers of no type, which can then be used however they are meant to be used by the function with the appropriate cast.
The void pointer, also known as the generic pointer, is a special type of pointer that can be pointed at objects of any data type! A void pointer is declared like a normal pointer, using the void keyword as the pointer’s type:
Since your only argument is a void pointer, you need to cast your argument to a void pointer each time. This is not necessary, but a habit at least, a bit similar to the cast when using malloc.
You may ask, what if you wanted to pass many arguments and not just one? The typical way to get through this is to encapsulate all your arguments into a struct, and then pass that struct.
4 Comments
*(int*(var)) and (int*)a ?*(int*(var)) is invalid syntax and won't compile.Your start_routine will take a pointer, but it doesn't care about the type of data to be found at this address. Therefore, it expects a void * and lets you afterwards use it as you wish.
Using a cast (void *) before your variable name will just prevent a warning when compiling your program.
Comments
The underlying OS provides the thread support and the OS does not care what language was used to write the code it runs. The OS thread API calls have to be independent of language features and so the 'CreateThread' call is usually designed to copy one pointer only to the stack of the new thread for retrieval by the thread function when it eventually runs. It is up to the language/code that creates new threads to use that pointer in an appropriate and correct manner. In the case of C/pthreads, this constraint surfaces as a void* pointer.
Everywhere I am seeing is (void*)myArray
Well, I often see a pointer to a dynamically-allocated struct or, in the case of OO languages, an object instance pointer/ref. I don't see why an array pointer would be any sort of 'favoured' type.