I quite enjoy working with multiple threads to speed up a program.
I recently wrote (what I considered) a high-performace timer which read commands in from a named pipe. This afforded the user the ability to script/program around my program as they please. I intend to put header files with all my #define
statements so other programs can use it effectively.
POSIX Threads, or pthreads, is technically a language-independent execution model for multi-threading a program, but here I refer to the implementation of said model in C’s standard library.
The biggest nuisance with pthread
is casting and packing all the parameters up into a void *
:
static void main(int argc, char * argv[])
{
...
// parameter packing
void * read_packed[3] = {(void *) &timer, (void *) pipe_path, (void *) &print_pipe[1]};
void * print_packed[3] = {(void *) &timer, (void *) stdout, (void *) &print_pipe[0]};
...
pthread_create(&read_thread, NULL, read_loop, read_packed);
pthread_create(&print_thread, NULL, print_loop, print_packed);
...
Then these parameters need be unpacked in the same way:
void * read_loop(void * param)
{
// parameter unpacking
void * * packed = (void * *) param;
Timer * timer = (Timer *) packed[0];
char * fifo_path = (char *) packed[1];
int * print_command_pipe = (int *) packed[2];
...
void * print_loop(void * param)
{
// parameter unpacking
void * * packed = (void * *) param;
Timer * timer = (Timer *) packed[0];
FILE * print_to = (FILE *) packed[1];
int * pipe = (int *) packed[2];
...
This is required because the pthread standard requires threads to share the heap with the main thread, but completely segregates each thread’s stack. So to start a thread with certain data, a pointer to where that data is in the stack is required.