How does pthread_create() work, and what is the thread function signature?
pthread_create() creates a new thread within the calling process.
Prototype:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
Parameters:
thread-- output parameter: stores the new thread's IDattr-- thread attributes (NULL for defaults: joinable, default stack size)start_routine-- function the thread will execute. Signature:void *func(void *arg)arg-- single argument passed to the start routine (use a struct for multiple values)
Return value: 0 on success, error number on failure (does NOT set errno).
Thread function signature: Must be void *(*)(void *) -- takes a void pointer, returns a void pointer. The return value is available to pthread_join().
Key points:
- The new thread starts executing
start_routineimmediately (scheduling order is indeterminate) - All threads share the process address space (global variables, heap, file descriptors)
- Each thread has its own stack, thread ID, errno, signal mask, and scheduling priority
- Compile and link with
-pthreadflag
1. Define thread function: void *worker(void *arg) { ... return result; }
2. pthread_t tid;
3. pthread_create(&tid, NULL, worker, arg)
4. Thread runs worker(arg) concurrently
5. pthread_join(tid, &result) -- wait for thread, get return value
6. Compile: gcc -pthread program.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int id;
const char *message;
} thread_arg_t;
void *worker(void *arg) {
thread_arg_t *ta = (thread_arg_t *)arg;
printf("Thread %d: %s\n", ta->id, ta->message);
/* Allocate and return a result */
int *result = malloc(sizeof(int));
*result = ta->id * 10;
return result;
}
int main(void) {
pthread_t threads[3];
thread_arg_t args[3] = {
{1, "Hello"}, {2, "World"}, {3, "!"}
};
/* Create threads */
for (int i = 0; i < 3; i++) {
int ret = pthread_create(&threads[i], NULL, worker, &args[i]);
if (ret != 0) {
fprintf(stderr, "pthread_create: %s\n", strerror(ret));
return 1;
}
}
/* Join threads and get results */
for (int i = 0; i < 3; i++) {
void *retval;
pthread_join(threads[i], &retval);
printf("Thread %d returned: %d\n", i + 1, *(int *)retval);
free(retval);
}
return 0;
}
- •Thread function signature: void *func(void *arg)
- •pthread_create returns 0 on success, error number on failure (not -1)
- •All threads share global memory, heap, and file descriptors
- •Each thread has its own stack, errno, and signal mask
- •Compile with -pthread flag
- •Passing a pointer to a local variable as arg can be a race if the variable changes before thread reads it
- •pthreads functions return error codes directly (not via errno)
- •Forgetting -pthread flag causes undefined behavior (may seem to work but fail at runtime)
- •Thread function must return void* -- returning without a value is undefined if pthread_join expects one