Master POSIX Threads (pthreads) in Linux (2026)

On: January 2, 2026
POSIX Threads (pthreads) in Linux

Learn POSIX Threads (pthreads) in Linux: thread creation, synchronization, mutexes, condition variables, and advanced concepts with practical examples & interview tips.

Multithreading is a fundamental concept in modern software development, especially in high-performance, real-time, and concurrent applications. POSIX Threads, commonly called pthreads, is the standard threading library in Unix/Linux systems. This article will give you a complete understanding of pthreads from basics to advanced concepts, with examples, diagrams, and interview tips.

1. Introduction to POSIX Threads

What are Threads?

  • A thread is the smallest unit of execution within a process.
  • Multiple threads can exist within the same process, sharing code, data, and resources like file descriptors and heap memory.
  • Each thread has its own stack, program counter (PC), and registers.

Example: A web server can use one thread per client request, sharing the same memory space for efficient communication.

Difference Between Processes and Threads

FeatureProcessThread
MemorySeparate memory spaceShares memory with other threads
OverheadHigher (context switching)Lower
CommunicationInter-process communication (IPC)Direct memory access
Creationfork()pthread_create()
Use-caseIsolation, heavy tasksLightweight, concurrent tasks

Interview Tip: Be ready to explain why threads are faster than processes for certain tasks, citing shared memory and low creation overhead.

Advantages and Use-Cases of Multithreading

Advantages:

  1. Responsiveness: GUI apps remain responsive while performing background tasks.
  2. Resource sharing: Threads share process memory, enabling easy communication.
  3. Better CPU utilization: Threads can run concurrently on multiple cores.
  4. Simplified program structure: Tasks like I/O and computation can run in parallel.

Use-Cases:

  • Web servers and database servers
  • Real-time embedded systems
  • Parallel computation tasks (matrix multiplication, video processing)
  • Producer-consumer pipelines

2. POSIX Threads Library Overview

What is pthreads?

  • POSIX Threads is a standard API for multithreading on Unix-like systems.
  • Implemented in <pthread.h>.
  • Supports thread creation, synchronization, attributes, cancellation, and real-time scheduling.

Including pthread library in C/C++ programs

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
  • Compiling programs requires linking the pthread library:
gcc myprogram.c -o myprogram -lpthread

3. Thread Creation and Termination

Using pthread_create()

void* thread_function(void* arg) {
    printf("Hello from thread! Received: %d\n", *(int*)arg);
    pthread_exit((void*) arg);  // Exit thread and return value
}

int main() {
    pthread_t tid;
    int value = 42;

    // Create a thread
    if (pthread_create(&tid, NULL, thread_function, (void*)&value) != 0) {
        perror("pthread_create failed");
        exit(1);
    }

    void* ret_val;
    pthread_join(tid, &ret_val); // Wait for thread to finish

    printf("Thread returned: %d\n", (int)(long)ret_val);
    return 0;
}

Explanation:

  1. pthread_t tid: Thread ID.
  2. pthread_create(): Creates a thread.
    • Arguments: Thread ID, attributes (NULL = default), thread function, arguments.
  3. pthread_exit(): Ends the thread.
  4. pthread_join(): Waits for a thread and retrieves its return value.

Interview Tip: Know the difference between pthread_exit() and return in a thread function.

4. Thread Attributes

  • pthread_attr_t is used to customize threads.

Common attributes:

  • Stack size: pthread_attr_setstacksize()
  • Detach state: Joinable or detached (pthread_attr_setdetachstate())
  • Scheduling policy: SCHED_FIFO, SCHED_RR, SCHED_OTHER

Example:

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 1024*1024); // 1 MB
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&tid, &attr, thread_function, (void*)&value);
pthread_attr_destroy(&attr);

5. Thread Detachment

  • Joinable Threads: Must be joined using pthread_join().
  • Detached Threads: Resources are automatically released when the thread exits.
pthread_detach(tid); // Detaches a joinable thread

Interview Tip: Explain the memory/resource leak problem if detached threads are not properly used.

6. Thread Synchronization

Multithreading introduces the risk of race conditions. Synchronization primitives prevent this.

Mutexes (pthread_mutex_t)

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&lock);   // Acquire lock
// Critical section
pthread_mutex_unlock(&lock); // Release lock
pthread_mutex_destroy(&lock);
  • Recursive Mutex: Same thread can lock multiple times.

Condition Variables (pthread_cond_t)

  • Used for signaling between threads.
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// Thread A waits
pthread_mutex_lock(&lock);
pthread_cond_wait(&cond, &lock); // Releases lock and waits
pthread_mutex_unlock(&lock);

// Thread B signals
pthread_mutex_lock(&lock);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
  • Broadcast wakes all waiting threads: pthread_cond_broadcast()

Reader-Writer Locks

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
pthread_rwlock_rdlock(&rwlock); // Acquire read lock
pthread_rwlock_wrlock(&rwlock); // Acquire write lock
pthread_rwlock_unlock(&rwlock);

7. Thread-Specific Data (TSD)

  • Each thread can have its own private data using pthread_key_t.
pthread_key_t key;
pthread_key_create(&key, free);

void* val = malloc(sizeof(int));
*(int*)val = 100;
pthread_setspecific(key, val);

int* myval = (int*)pthread_getspecific(key);
printf("Thread-specific data: %d\n", *myval);

8. Thread Cancellation and Cleanup

Thread Cancellation

pthread_cancel(tid); // Request thread termination
  • Types: Asynchronous (immediate) or Deferred (at cancellation points)

Cleanup Handlers

void cleanup(void* arg) { printf("Cleaning: %s\n", (char*)arg); }
pthread_cleanup_push(cleanup, "Thread resources");
pthread_cleanup_pop(1); // Execute cleanup

9. Advanced Thread Topics

Scheduling Policies and Priorities

  • SCHED_FIFO: First-in-first-out real-time
  • SCHED_RR: Round-robin real-time
  • SCHED_OTHER: Default Linux timesharing

Signal Handling

  • Signals can be masked per-thread using pthread_sigmask().

Deadlocks

  • Avoid nested locks
  • Use pthread_mutex_trylock() to prevent waiting forever
  • Lock ordering strategy

10. Best Practices and Interview Tips

  1. Always initialize and destroy mutexes, condition variables.
  2. Prefer joinable threads if you need a return value.
  3. Avoid sharing mutable global variables without synchronization.
  4. Minimize critical section to improve performance.
  5. Use thread-specific data to avoid data races.
  6. Understand pthread attribute usage for real-time and embedded systems.
  7. Be ready to explain common pitfalls like deadlocks, resource leaks, and race conditions.

11. Example Programs

Simple Thread Creation

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

void* say_hello(void* arg) {
    printf("Hello from thread!\n");
    return NULL;
}

int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, say_hello, NULL);
    pthread_join(tid, NULL);
    return 0;
}

Producer-Consumer Problem

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

#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE], count = 0;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER;
pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;

void* producer(void* arg) {
    for (int i=0;i<10;i++){
        pthread_mutex_lock(&lock);
        while(count == BUFFER_SIZE) pthread_cond_wait(&not_full, &lock);
        buffer[count++] = i;
        printf("Produced: %d\n", i);
        pthread_cond_signal(&not_empty);
        pthread_mutex_unlock(&lock);
    }
    return NULL;
}

void* consumer(void* arg) {
    for(int i=0;i<10;i++){
        pthread_mutex_lock(&lock);
        while(count == 0) pthread_cond_wait(&not_empty, &lock);
        int val = buffer[--count];
        printf("Consumed: %d\n", val);
        pthread_cond_signal(&not_full);
        pthread_mutex_unlock(&lock);
    }
    return NULL;
}

int main() {
    pthread_t p, c;
    pthread_create(&p, NULL, producer, NULL);
    pthread_create(&c, NULL, consumer, NULL);
    pthread_join(p, NULL);
    pthread_join(c, NULL);
    return 0;
}

Thread-Specific Data Example

pthread_key_t key;

void* thread_func(void* arg) {
    int* val = malloc(sizeof(int));
    *val = *(int*)arg;
    pthread_setspecific(key, val);
    printf("Thread-specific data: %d\n", *(int*)pthread_getspecific(key));
    return NULL;
}

POSIX Threads (pthreads) Interview Questions

1. Basics of Threads and Pthreads

Beginner Questions

  1. What is a thread? How does it differ from a process?
  2. What are the advantages of using threads over processes?
  3. Explain multithreading with an example.
  4. What is POSIX Threads (pthreads)? Why is it used?
  5. How do you include pthread library in a C/C++ program?
  6. How do you compile a pthread program in Linux? (-lpthread)
  7. What is the difference between user-level threads and kernel-level threads?
  8. Can threads share memory? Which resources are shared, and which are private?

Intermediate Questions
9. Explain the thread lifecycle (New, Runnable, Running, Waiting, Terminated).
10. What is a thread ID (pthread_t)? How is it used?
11. What is a joinable thread vs a detached thread?

Advanced Questions
12. Explain the differences between POSIX threads and Windows threads.
13. What are some common pitfalls when using threads in Linux?

2. Thread Creation and Termination

Beginner Questions

  1. How do you create a thread in pthreads? Explain pthread_create() arguments.
  2. What is the prototype of a thread function?
  3. How do threads terminate? Difference between pthread_exit() and returning from thread function.
  4. How do you wait for a thread to finish? Explain pthread_join().

Intermediate Questions
5. Can a thread return a value? How?
6. What happens if pthread_join() is not called for a joinable thread?
7. What is the effect of calling exit() inside a thread?

Advanced Questions
8. How can you handle multiple threads returning different data types?
9. Explain thread stack allocation and stack size management.

3. Thread Attributes (pthread_attr_t)

Beginner Questions

  1. What are thread attributes? Why are they used?
  2. How do you initialize and destroy thread attributes? (pthread_attr_init, pthread_attr_destroy)

Intermediate Questions
3. How do you set a thread as detached using attributes?
4. How do you set a custom stack size?
5. How do you set scheduling policy using attributes? (SCHED_FIFO, SCHED_RR, SCHED_OTHER)

Advanced Questions
6. What are real-time thread attributes and their significance?
7. How do thread attributes affect performance and memory usage?

4. Thread Detachment

Beginner Questions

  1. What is the difference between detached and joinable threads?
  2. How do you detach a thread after creation? (pthread_detach)

Intermediate Questions
3. What happens if a detached thread calls pthread_exit()?
4. Can you join a detached thread? Why or why not?

Advanced Questions
5. When should you use detached threads in real-world applications?

5. Thread Synchronization

Mutexes

Beginner Questions

  1. What is a mutex? Why is it needed?
  2. How do you initialize, lock, unlock, and destroy a mutex?
  3. What happens if a thread tries to unlock a mutex it does not own?

Intermediate Questions
4. What is a recursive mutex? When is it used?
5. Explain deadlocks with an example in multithreaded programs.
6. How can deadlocks be avoided in pthread programs?

Advanced Questions
7. Explain priority inversion and how to handle it in pthreads.

Condition Variables

Beginner Questions

  1. What is a condition variable?
  2. How do pthread_cond_wait(), pthread_cond_signal(), and pthread_cond_broadcast() work?

Intermediate Questions
3. Why do you need a mutex with condition variables?
4. What is spurious wakeup, and how do you handle it?

Advanced Questions
5. Explain producer-consumer problem using mutex and condition variables.

Reader-Writer Locks

Beginner Questions

  1. What is a reader-writer lock (pthread_rwlock_t)?
  2. How is it different from a mutex?

Intermediate Questions
3. How do you acquire read and write locks? (pthread_rwlock_rdlock, pthread_rwlock_wrlock)
4. What happens if multiple writers try to acquire the lock simultaneously?

6. Thread-Specific Data (TSD)

Beginner Questions

  1. What is thread-specific data?
  2. How do you create a pthread_key_t?

Intermediate Questions
3. How do you set and get thread-specific data? (pthread_setspecific, pthread_getspecific)
4. How is thread-specific data useful in real applications?

Advanced Questions
5. How do you cleanup thread-specific data automatically?

7. Thread Cancellation and Cleanup

Beginner Questions

  1. How do you cancel a thread? (pthread_cancel)
  2. What is the difference between asynchronous and deferred cancellation?

Intermediate Questions
3. How do you set a thread as cancellable or non-cancellable?
4. What are cleanup handlers? (pthread_cleanup_push, pthread_cleanup_pop)

Advanced Questions
5. How do you ensure resources are freed when a thread is cancelled?

8. Advanced Thread Topics

Scheduling and Real-time

Beginner Questions

  1. What are the POSIX thread scheduling policies? (SCHED_FIFO, SCHED_RR, SCHED_OTHER)
  2. How do you set thread priority?

Intermediate Questions
3. How is real-time scheduling different from normal scheduling?
4. What are the limitations of real-time threads in Linux?

Signal Handling in Threads

  1. How are signals delivered in multithreaded programs?
  2. How do you block/unblock signals for a thread? (pthread_sigmask)

Deadlocks

  1. What is a deadlock?
  2. How can you detect and prevent deadlocks?
  3. Explain lock hierarchy and timeout-based strategies.

9. Best Practices Questions

  1. What are common pitfalls in pthread programming?
  2. How do you avoid race conditions?
  3. How should multithreaded programs be structured for safety and efficiency?
  4. How do you optimize performance in multithreaded programs?
  5. How do you debug pthread programs? (gdb, helgrind, valgrind)

10. Practical and Coding Questions (Interview-Focused)

  1. Write a simple program that creates multiple threads and prints messages.
  2. Implement a producer-consumer problem using mutexes and condition variables.
  3. Implement a thread-safe counter using mutex or atomic operations.
  4. Demonstrate using thread-specific data.
  5. Write a program where threads are detached and cannot be joined.
  6. Simulate deadlock and show how to fix it.
  7. Demonstrate cancelling a thread and cleaning up resources.
  8. Implement a reader-writer scenario using pthread_rwlock_t.

Conclusion

  • POSIX threads allow efficient, lightweight multithreading in Linux.
  • Key interview topics: pthread_create, pthread_join, mutexes, condition variables, thread attributes, thread cancellation, TSD, and deadlock avoidance.
  • Practice coding small multithreaded programs, and always reason about synchronization and data sharing.
  • Advanced topics: Real-time scheduling, signal handling, and performance optimization are often asked in senior-level interviews.

Recommended Resources:

  • “Programming with POSIX Threads” by David R. Butenhof
  • Linux man pages: man pthread_create, man pthread_mutex_lock
  • Online tutorials and example repositories on GitHub

FAQ : POSIX Threads (pthreads)

1. What are POSIX Threads (pthreads) in Linux?

Answer:
POSIX Threads, or pthreads, are a standardized way to create and manage multithreaded programs in Linux. Threads allow a program to execute multiple tasks concurrently within the same process, sharing memory and resources while maintaining separate execution contexts.

2. How do I create a thread using pthreads in C/C++?

Answer:
You create a thread using pthread_create(). It requires a thread ID, optional thread attributes, the thread function, and an argument. Example:

pthread_t tid;
pthread_create(&tid, NULL, thread_function, (void*)&arg);

This starts a new thread executing thread_function.

3. What is the difference between processes and threads?

Answer:

  • Processes have separate memory spaces, heavier to create, and use IPC to communicate.
  • Threads share the same memory space, are lightweight, and communicate directly through shared variables.
    Threads are ideal for concurrent execution, while processes are better for isolation and fault tolerance.

4. How can I wait for a thread to finish in pthreads?

Answer:
Use pthread_join() to wait for a joinable thread to complete and optionally retrieve its return value:

void* retval;
pthread_join(tid, &retval);

Detached threads cannot be joined, and their resources are automatically freed after completion.

5. What are pthread mutexes and why are they important?

Answer:
A mutex (mutual exclusion) is a synchronization primitive used to prevent race conditions when multiple threads access shared data. Operations include lock, unlock, and destroy:

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&lock); // Critical section
pthread_mutex_unlock(&lock);

6. What is the purpose of condition variables in pthreads?

Answer:
Condition variables allow threads to wait for certain conditions before proceeding, typically used with mutexes. They support signaling one or all threads when a condition changes:

pthread_cond_wait(&cond, &mutex);
pthread_cond_signal(&cond);
pthread_cond_broadcast(&cond);

Use-case: Implementing producer-consumer problems.

7. What is thread-specific data (TSD) in pthreads?

Answer:
Thread-specific data allows each thread to store its own private data using a key (pthread_key_t), even if multiple threads run the same function:

pthread_key_t key;
pthread_setspecific(key, data);
void* val = pthread_getspecific(key);

This is useful for per-thread storage in libraries or reusable modules.

8. How do you cancel a thread safely in pthreads?

Answer:
Use pthread_cancel() to request thread termination. Threads can be asynchronous or deferred cancellable, and you can use cleanup handlers to release resources:

pthread_cleanup_push(cleanup_function, arg);
pthread_cleanup_pop(1);

9. What are detached threads and how are they different from joinable threads?

Answer:

  • Joinable threads require pthread_join() to free resources.
  • Detached threads free resources automatically when they finish.
    Use pthread_detach(tid) to detach a thread. Detached threads are ideal for background tasks where you don’t need the return value.

10. What are common pitfalls in pthread programming?

Answer:

  1. Race conditions due to unsynchronized shared memory.
  2. Deadlocks caused by nested or circular locking.
  3. Forgetting to destroy mutexes/condition variables.
  4. Improper use of detached threads leading to memory/resource leaks.
  5. Ignoring thread cancellation and cleanup.

Best Practice: Always use mutexes, condition variables, and cleanup handlers for safe multithreaded programs.

Read More : IPC in Linux

Leave a Comment

Exit mobile version