All thread create methods like pthread_create() or CreateThread() in Windows expect the caller to provide a pointer to the arg for the thread. Isn’t this inherently unsafe?
This can work ‘safely’ only if the arg is in the heap, and then again creating a heap variable
adds to the overhead of cleaning the allocated memory up. If a stack variable is provided as the arg then the result is at best unpredictable.
This looks like a half-cooked solution to me, or am I missing some subtle aspect of the APIs?
Context.
Many C APIs provide an extra
void *argument so that you can pass context through third party APIs. Typically you might pack some information into a struct and point this variable at the struct, so that when the thread initializes and begins executing it has more information than the particular function that its started with. There’s no necessity to keep this information at the location given. For instance you might have several fields that tell the newly created thread what it will be working on, and where it can find the data it will need. Furthermore there’s no requirement that thevoid *actually be used as a pointer, its a typeless argument with the most appropriate width on a given architecture (pointer width), that anything can be made available to the new thread. For instance you might pass anintdirectly ifsizeof(int) <= sizeof(void *):(void *)3.As a related example of this style: A FUSE filesystem I’m currently working on starts by opening a filesystem instance, say
struct MyFS. When running FUSE in multithreaded mode, threads arrive onto a series of FUSE-defined calls for handlingopen,read,stat, etc. Naturally these can have no advance knowledge of the actual specifics of my filesystem, so this is passed in thefuse_mainfunctionvoid *argument intended for this purpose.struct MyFS *blah = myfs_init(); fuse_main(..., blah);. Now when the threads arrive at the FUSE calls mentioned above, thevoid *received is converted back intostruct MyFS *so that the call can be handled within the context of the intended MyFS instance.