Linux System Programming · intermediate · ~10 min

Returning data from threads

Return values from a thread back to its joiner.

Lesson

Threads return void *. The joiner passes void ** to pthread_join and gets the pointer back. The pointer must remain valid after the thread exits:

  • Cast a value into the pointer ((void *)(intptr_t)42) — safe for ints up to pointer width.
  • Return a static or global — works but isn't reentrant.
  • Return a malloc'd struct — joiner is responsible for freeing.
  • Returning a stack address is always wrong — the thread's stack is gone the moment it exits.

Code examples

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct { int sum; int count; } result_t;

static void *worker(void *arg) {
    int n = (int)(intptr_t)arg;
    result_t *r = malloc(sizeof *r);
    r->sum = n * (n + 1) / 2;
    r->count = n;
    return r;
}

int main(void) {
    pthread_t t;
    pthread_create(&t, NULL, worker, (void *)(intptr_t)10);

    void *raw;
    pthread_join(t, &raw);
    result_t *r = raw;
    printf("sum=%d count=%d\n", r->sum, r->count);
    free(r);
    return 0;
}

Common mistakes

  • Returning a stack address. The thread's stack is invalid after it exits.
  • Forgetting to free the malloc'd return on the joiner side. Memory leak.

Summary

Threads return void *. Safe options: a value-cast int, a global, or a malloc'd buffer the joiner frees. Never a stack-local address.

Practice with these exercises