#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
typedef struct thread_task_s thread_task_t;
typedef struct thread_pool_s thread_pool_t;
struct thread_task_s
{
void *(*process)(void *arg);
void *arg;
thread_task_t *next;
};
struct thread_pool_s
{
pthread_mutex_t queue_lock;
pthread_cond_t queue_ready;
thread_task_t *task_queue;
thread_task_t *task_queue_tail;
bool shutdown;
pthread_t *thread_id;
int max_thread_num;
int cur_queue_size;
};
int thread_pool_add_task(thread_pool_t *pool, void * (*process)(void *), void *arg);
void *thread_routine(void *arg);
int thread_pool_create(thread_pool_t **thread_pool, int max_thread_num)
{
thread_pool_t *pool;
pool = malloc(sizeof(thread_pool_t));
if (pool == NULL)
return -1;
pthread_mutex_init(&(pool->queue_lock), NULL);
pthread_cond_init(&(pool->queue_ready), NULL);
pool->task_queue = pool->task_queue_tail = NULL;
pool->max_thread_num = max_thread_num;
pool->cur_queue_size = 0;
pool->shutdown = 0;
pool->thread_id = malloc(sizeof(pthread_t) * max_thread_num);
for(int i = 0; i != max_thread_num; ++i) {
pthread_create(&(pool->thread_id[i]), NULL, thread_routine, pool);
}
*thread_pool = pool;
return 0;
}
int thread_pool_add_task(thread_pool_t *pool, void *(*process)(void *), void *arg)
{
if (pool->shutdown == true) {
return -1;
}
thread_task_t *task = (thread_task_t *)malloc(sizeof(thread_task_t));
task->process = process;
task->arg = arg;
task->next = NULL;
pthread_mutex_lock(&(pool->queue_lock));
if (pool->task_queue != NULL) {
pool->task_queue_tail->next = task;
pool->task_queue_tail = task;
}
else {
pool->task_queue = pool->task_queue_tail = task;
}
pool->cur_queue_size++;
pthread_mutex_unlock(&(pool->queue_lock));
pthread_cond_signal(&(pool->queue_ready));
return 0;
}
int thread_pool_destroy(thread_pool_t *pool)
{
if (pool->shutdown) {
return -1;
}
pool->shutdown = true;
pthread_cond_broadcast(&(pool->queue_ready));
for (int i = 0; i != pool->max_thread_num; ++i) {
pthread_join(pool->thread_id[i], NULL);
}
free(pool->thread_id);
thread_task_t *task;
while (pool->task_queue != NULL) {
task = pool->task_queue;
pool->task_queue = task->next;
free(task);
}
pthread_mutex_destroy(&(pool->queue_lock));
pthread_cond_destroy(&(pool->queue_ready));
free(pool);
return 0;
}
void *thread_routine(void *arg)
{
printf("thread %d starting!\r\n", pthread_self());
for ( ; ; ) {
thread_pool_t * pool = (thread_pool_t *)arg;
pthread_mutex_lock(&(pool->queue_lock));
if (pool->cur_queue_size == 0 && !pool->shutdown) {
pthread_cond_wait(&(pool->queue_ready), &(pool->queue_lock));
}
printf("thread %d get lock\r\n", pthread_self());
if (pool->shutdown) {
pthread_mutex_unlock(&(pool->queue_lock));
printf("thread %d will exit!\r\n", pthread_self());
pthread_exit(NULL);
}
if (pool->task_queue != NULL && pool->cur_queue_size != 0) {
printf("thread %d will start work!\r\n", pthread_self());
pool->cur_queue_size--;
thread_task_t *task = pool->task_queue;
pool->task_queue = task->next;
pthread_mutex_unlock(&(pool->queue_lock));
(*(task->process))(task->arg);
free(task);
}
}
pthread_exit(NULL);
}
void * print_number(void * arg)
{
for(int i = 0; i != 10; ++i) {
printf("%d\r\n", (int)arg);
}
}
int main(int argc, char **argv)
{
thread_pool_t *thread_pool;
thread_pool_create(&thread_pool, 10);
sleep(5);
thread_pool_add_task(thread_pool, print_number, (void *)1);
thread_pool_add_task(thread_pool, print_number, (void *)2);
sleep(5);
thread_pool_destroy(thread_pool);
}
linux下c语言简单线程池实现
最新推荐文章于 2024-07-24 22:30:00 发布