Thread creation: pthread_create
pthread_create
- Spawns a new thread running
fn(arg). The kernel decides when the
child actually starts — could be before or after the parent’s next line.
- Signature:
int pthread_create(pthread_t *t, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
attr is almost always NULL (default attributes).
Arguments: one void * slot
- Only a single
void * gets through. To pass multiple values, bundle
them in a struct and hand over its address:
typedef struct { int a; double b; } myarg_t;
myarg_t args = { 10, 12.34 };
pthread_create(&t, NULL, mythread, &args);
- Inside the start routine, cast back:
myarg_t *m = (myarg_t *) arg;.
Lifetime
sequenceDiagram
participant P as Parent
participant T as Child thread
P->>T: pthread_create(fn, &args)
T->>T: fn(args) runs
T-->>P: returns void *retval
P->>T: pthread_join(t, &retval)
- The caller owns the storage you point
arg at. If args lives on
the parent’s stack and the parent returns before the child reads it,
the child reads garbage.
- A thread returning a pointer into its own stack is just as
broken — the stack unwinds at exit. Use heap or a caller-owned buffer.
Error reporting
pthread_create returns the error code directly (0 on success).
- Does not touch
errno. Reading errno after pthread_create is a bug.
- Common failure:
EAGAIN (system out of resources for another thread).
Quiz yourself
- When you need multiple arguments, what does the canonical pattern look like?
- Why is returning a pointer to a stack variable from a thread dangerous?