C Threads Library (<threads.h>)
Multi-threading support in C11
๐งต What is threads.h?
The threads.h header provides portable multi-threading support in C11. It allows you to create and manage multiple threads of execution, enabling concurrent programming with thread creation, synchronization, and communication.
#include <threads.h>
#include <stdio.h>
int thread_function(void* arg) {
printf("Hello from thread!\n");
return 0;
}
Key Threading Concepts
Thread Creation
Create new threads with thrd_create
thrd_t thread;
thrd_create(&thread, func, NULL);
Mutexes
Synchronize access to shared data
mtx_t mutex;
mtx_init(&mutex, mtx_plain);
mtx_lock(&mutex);
Thread Sleep
Pause thread execution
struct timespec ts = {1, 0};
thrd_sleep(&ts, NULL);
Thread Join
Wait for thread completion
int result;
thrd_join(thread, &result);
๐น Basic Thread Example
Multithreading in C allows programs to execute multiple tasks concurrently using the POSIX threads (pthreads) library. The pthread_create() function launches a new thread that executes a specified function with optional arguments, while pthread_join() waits for a thread to complete and retrieves its return value. For example, creating a thread involves defining a thread function with signature void* function(void* arg) and passing it to pthread_create(). Threads share the same memory space as the parent process, enabling efficient communication but requiring careful synchronization to prevent race conditions and data corruption in concurrent access scenarios.
#include <threads.h>
#include <stdio.h>
int worker_thread(void* arg) {
int* number = (int*)arg;
printf("Thread received: %d\n", *number);
return *number * 2;
}
int main() {
thrd_t thread;
int data = 42;
int result;
// Create thread
if (thrd_create(&thread, worker_thread, &data) != thrd_success) {
printf("Failed to create thread\n");
return 1;
}
// Wait for thread to complete
thrd_join(thread, &result);
printf("Thread returned: %d\n", result);
return 0;
}
Output:
Thread received: 42
Thread returned: 84
๐น Mutex Synchronization
Mutex (mutual exclusion) locks protect shared data from race conditions in multithreaded programs using the pthreads library. A mutex ensures that only one thread can access a critical section of code at a time by calling pthread_mutex_lock() before entering and pthread_mutex_unlock() after exiting the protected region. For example, when multiple threads increment a shared counter, wrapping the increment operation with mutex locks prevents lost updates caused by concurrent access. Without proper synchronization, race conditions occur where multiple threads read and write shared variables simultaneously, producing incorrect results and unpredictable behavior that's difficult to debug in concurrent applications.
#include <threads.h>
#include <stdio.h>
mtx_t counter_mutex;
int shared_counter = 0;
int increment_thread(void* arg) {
for (int i = 0; i < 1000; i++) {
mtx_lock(&counter_mutex);
shared_counter++;
mtx_unlock(&counter_mutex);
}
return 0;
}
int main() {
thrd_t threads[2];
// Initialize mutex
mtx_init(&counter_mutex, mtx_plain);
// Create two threads
for (int i = 0; i < 2; i++) {
thrd_create(&threads[i], increment_thread, NULL);
}
// Wait for both threads
for (int i = 0; i < 2; i++) {
thrd_join(threads[i], NULL);
}
printf("Final counter value: %d\n", shared_counter);
mtx_destroy(&counter_mutex);
return 0;
}