design a threadpool in pure C

actually this post should be named as “pure C multithreads”, while it’s better to write some real code. a simple threadpool in pure C

exposed APIs

at most simple case, what a threadpool object should do?

thpool_init(num_threads);
thpool_destory(threapool_obj);
thpool_add_work(callback, args); 
// so user define event callback() can be passed in;  

threadpool is used to assign jobs (from job list) to a thread. so joblist should be an internal class; and it’s better to package thread, job as separate class too; to add work, what kind of funcs need for joblist ? at least, to add new job(from outside) to the joblist.

internal structures:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
struct thread {
int id;
pthread_t thread; //pthread_t is a unsigned long int; it's system assigned
threadpool *thpool; //so thread know its domain
}
struct job {
(void*) func(void*); // each job/task should have a callback func
(void*) func_arg ; //and func args
//since consider joblist as a list, it's helpful to add pointers to neighbors
job* prev;
job* next;
}
struct jobqueue {
int num_jobs;
job* front;
job* rear;
//some flags to support add new node(job) to the list
}
struct threadpool_ {
thread* threads_array;
jobqueue job_queue;
// some flags
}

consider syncronlization

will multi threads call add_task() simutaneously? if so, jobqueue should have a mutex object;

1
2
3
4
5
6
struct jobqueue {
int num_jobs;
job* front;
job* rear;
pthread_mutex_t jq_mutex;
}

during threadpool initialization, will all threads be created simultaneously and immediately? if not, there should be thread status flags (creating, exisiting-but-idle, working, died); and to update these flags need protect by mutex object;

1
2
3
4
5
6
struct threadpool_ {
thread* threads_array;
jobqueue job_queue;
int num_threads; //stands for the number of all existing threads
pthread_mutex_t tp_mutex;
}

this is an interesting, when design a lib, what’s in my mind. hopefully implement by the end of week.