Build a Minimal C Thread Pool on Linux – Full Code Walkthrough
This article presents a compact C thread‑pool implementation for Linux using POSIX pthreads, explains the core data structures and functions, shows how to create, enqueue tasks, and destroy the pool, and includes a runnable demo with annotated source code.
Overview
Provides a minimal POSIX thread‑pool implementation in C (~100 lines). The pool supports dynamic task‑queue growth, graceful shutdown, and demonstrates concurrent execution.
Key Data Structures
typedef struct Task {
void (*function)(void *arg);
void *arg;
} Task;
typedef struct ThreadPool {
pthread_t *threads; /* worker threads */
Task *taskQueue; /* circular queue */
int taskQueueSize; /* number of slots currently used */
int taskQueueCapacity; /* allocated capacity */
int head; /* index of next task to fetch */
int tail; /* index for next insertion */
int count; /* number of pending tasks */
pthread_mutex_t lock; /* protects queue */
pthread_cond_t cond; /* signals new tasks */
int stop; /* shutdown flag */
} ThreadPool;Worker Thread Function
void *worker(void *arg) {
ThreadPool *pool = (ThreadPool *)arg;
while (1) {
Task task;
pthread_mutex_lock(&pool->lock);
while (pool->count == 0 && !pool->stop) {
pthread_cond_wait(&pool->cond, &pool->lock);
}
if (pool->stop) {
pthread_mutex_unlock(&pool->lock);
break;
}
task = pool->taskQueue[pool->head];
pool->head = (pool->head + 1) % pool->taskQueueCapacity;
pool->count--;
pthread_mutex_unlock(&pool->lock);
task.function(task.arg);
}
return NULL;
}Creating a Thread Pool
ThreadPool *threadPoolCreate(int numThreads) {
ThreadPool *pool = malloc(sizeof(ThreadPool));
pool->taskQueueCapacity = 16;
pool->taskQueue = malloc(sizeof(Task) * pool->taskQueueCapacity);
pool->taskQueueSize = 0;
pool->head = pool->tail = pool->count = 0;
pool->stop = 0;
pool->threads = malloc(sizeof(pthread_t) * numThreads);
pthread_mutex_init(&pool->lock, NULL);
pthread_cond_init(&pool->cond, NULL);
for (int i = 0; i < numThreads; ++i) {
pthread_create(&pool->threads[i], NULL, worker, pool);
}
return pool;
}Enqueueing a Task
void threadPoolEnqueue(ThreadPool *pool,
void (*function)(void *), void *arg) {
pthread_mutex_lock(&pool->lock);
if (pool->count == pool->taskQueueCapacity) {
pool->taskQueueCapacity *= 2;
pool->taskQueue = realloc(pool->taskQueue,
sizeof(Task) * pool->taskQueueCapacity);
}
pool->taskQueue[pool->tail].function = function;
pool->taskQueue[pool->tail].arg = arg;
pool->tail = (pool->tail + 1) % pool->taskQueueCapacity;
pool->count++;
pthread_cond_signal(&pool->cond);
pthread_mutex_unlock(&pool->lock);
}Destroying the Pool
void threadPoolDestroy(ThreadPool *pool) {
pthread_mutex_lock(&pool->lock);
pool->stop = 1;
pthread_cond_broadcast(&pool->cond);
pthread_mutex_unlock(&pool->lock);
for (int i = 0; i < pool->taskQueueSize; ++i) {
pthread_join(pool->threads[i], NULL);
}
free(pool->taskQueue);
free(pool->threads);
free(pool);
}Example Usage
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void exampleTask(void *arg) {
int id = *(int *)arg;
printf("Running task %d
", id);
sleep(1);
}
int main(void) {
ThreadPool *pool = threadPoolCreate(4);
for (int i = 0; i < 10; ++i) {
int *id = malloc(sizeof(int));
*id = i;
threadPoolEnqueue(pool, exampleTask, id);
}
sleep(5); /* allow workers to finish */
threadPoolDestroy(pool);
return 0;
}Execution Result
The program prints “Running task X” for each enqueued task, demonstrating that multiple threads process tasks concurrently and that the pool cleans up correctly.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
