Great question! Understanding POSIX threads (pthreads) can be tricky at first, especially when you're still getting comfortable with pointers and how function arguments work in C.
Let's break down the code and explain what's happening step-by-step.
void *add(void *p_in)
mean?void *
before add
means this function returns a void *
pointer — this is required because the thread start routine in pthreads must have the signature:
void *function_name(void *argument);
The parameter (void *p_in)
means add
accepts a generic pointer to any data type (a void *
), which allows you to pass any kind of argument to the thread function.
add
function:pair_t *p = (pair_t *)p_in;
Here, you cast the generic pointer p_in
back to a pointer of type pair_t *
. This lets you access the members of the struct (a
and b
).
p->a
means "the a
member of the struct that p
points to."
The function then prints the sum p->a + p->b
.
adder(int x, int y)
?You create a new thread variable t
.
You create a local struct pair_t p
and set its members to x
and y
.
You call pthread_create()
with:
&t
: pointer to thread identifier,
NULL
: default thread attributes,
add
: the function to run in the new thread,
(void *)&p
: pointer to the argument passed to add
.
Yes, the thread arguments are passed to the add
function via the last argument to pthread_create()
.
The main issue here is the lifetime of the pair_t p
variable passed to the thread.
p
is a local variable inside adder()
. Once adder()
returns, the memory for p
may become invalid.
The new thread may try to access p
after it is no longer valid, leading to undefined behavior or incorrect results.
To ensure the data passed to the thread remains valid until the thread finishes, you should dynamically allocate the pair_t
struct on the heap, like this:
void adder(int x, int y) {
pthread_t t;
pair_t *p = malloc(sizeof(pair_t)); // allocate memory on heap
p->a = x;
p->b = y;
pthread_create(&t, NULL, add, (void *)p);
pthread_detach(t); // detach thread if you don't want to join later
}
Also, inside the add
function, after using p
, free the allocated memory:
void *add(void *p_in) {
pair_t *p = (pair_t *)p_in;
printf("Answer is: %d\n", p->a + p->b);
free(p); // free heap memory to avoid memory leak
return NULL;
}
For a complete beginner-friendly guide to POSIX threads, including examples, synchronization primitives like mutexes and condition variables, and debugging tips, check out this detailed tutorial on Embedded Prep:
🔗 POSIX Threads (pthreads) Beginner's Guide in C/C++