Linux System Programming · intermediate · ~10 min
Pass per-thread data into pthread_create — without sharing a loop variable.
A thread function has signature void *fn(void *arg). You pass exactly one pointer. To send multiple values, pack them into a struct and pass its address.
Critical bug pattern: passing the address of a loop variable.
/* WRONG — every thread reads the same `i` */
for (int i = 0; i < N; i++)
pthread_create(&tids[i], NULL, worker, &i);
By the time the threads run, the loop has finished and i == N. All threads read N. The fix: pass by value (cast int to/from intptr_t), or allocate a per-thread struct on the heap.
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
static void *worker(void *arg) {
int my_id = (int)(intptr_t)arg;
printf("thread %d alive\n", my_id);
return NULL;
}
int main(void) {
pthread_t tids[4];
for (int i = 0; i < 4; i++) {
/* cast int -> intptr_t -> void* keeps the value, not an address */
pthread_create(&tids[i], NULL, worker, (void *)(intptr_t)i);
}
for (int i = 0; i < 4; i++) pthread_join(tids[i], NULL);
return 0;
}
&i from a loop. All threads see the post-loop value of i.malloc'd args or pass by value.Pass one pointer; pack multiple values in a struct. Never pass the address of a stack-local loop variable — the loop will reassign it before the thread reads.