linux线程池

来源:互联网 发布:网络婚恋金融诈骗 编辑:程序博客网 时间:2024/05/29 11:19

线程池

1、任务和线程池结构体

#ifndef __THREADPOOL_H__#define __THREADPOOL_H__#include "condition.h"// 任务节点typedef struct task {void *(*run)(void *arg);// 回调函数void *arg;// 回调函数的参数struct task *next;}task_t;// 线程池的结构体typedef struct threadpool {condition_t ready;  // 同步和互斥的条件task_t *first;      // 任务队列的队头指针task_t *last;// 任务队列的队尾指针int counter;// 当前的线程数int idle;// 空闲线程数int max_threads;// 线程池允许的最大线程数int quit;// 线程的退出标记,1表示退出}threadpool_t;// 初始化线程池// @pool - 线程池对象// @threads - 线程池的最大数量void threadpool_init(threadpool_t *pool, int threads);// 向线程池中添加任务// @run - 任务回调函数void threadpool_add_task(threadpool_t *pool, void *(*run)(void*), void *arg);// 销毁线程池void threadpool_destroy(threadpool_t *pool);#endif //__THREADPOOL_H__

2、执行任务的条件

#ifndef __CONDITION_H__#define __CONDITION_H__#include <pthread.h>typedef struct condtion{pthread_mutex_t mutex;pthread_cond_t cond;}condition_t;void condition_init(condition_t *cond);void condition_lock(condition_t *cond);void condition_unlock(condition_t *cond);void condition_wait(condition_t *cond);int condition_timedwait(condition_t *cond, const struct timespec *abstime);void condition_signal(condition_t *cond);void condition_broadcast(condition_t *cond);void condition_destroy(condition_t *cond);#endif //__CONDITION_H__
#include "condition.h"void condition_init(condition_t *cond){pthread_mutex_init(&cond->mutex, NULL);pthread_cond_init(&cond->cond, NULL);}void condition_lock(condition_t *cond){pthread_mutex_lock(&cond->mutex);}void condition_unlock(condition_t *cond){pthread_mutex_unlock(&cond->mutex);}void condition_wait(condition_t *cond){pthread_cond_wait(&cond->cond, &cond->mutex);}int condition_timedwait(condition_t *cond, const struct timespec *abstime){return pthread_cond_timedwait(&cond->cond, &cond->mutex, abstime);}void condition_signal(condition_t *cond){pthread_cond_signal(&cond->cond);}void condition_broadcast(condition_t *cond){pthread_cond_broadcast(&cond->cond);}void condition_destroy(condition_t *cond){pthread_mutex_destroy(&cond->mutex);pthread_cond_destroy(&cond->cond);}

3、线程池实现

#include "threadpool.h"#include <stdio.h>#include <stdlib.h>#include <errno.h>void threadpool_init(threadpool_t *pool, int threads){condition_init(&pool->ready);pool->first       = NULL;pool->last        = NULL;pool->counter     = 0;pool->idle        = 0;pool->max_threads = threads;pool->quit        = 0;}void *route(void *arg){threadpool_t *pool = (threadpool_t*)arg;int timeout = 0;while ( 1 ) {condition_lock(&pool->ready);timeout = 0;pool->idle++;// 等待任务队列有任务到来或线程销毁通知while ( pool->first == NULL && pool->quit == 0 ) {//condition_wait(&pool->ready);struct timespec ts;clock_gettime(CLOCK_REALTIME, &ts);ts.tv_sec += 2;int ret = condition_timedwait(&pool->ready, &ts);if ( ret == ETIMEDOUT ) {printf("%#X thread timeout!\n", (int)pthread_self());timeout = 1;break;}}// 等待到条件,空闲线程数量减少pool->idle--;if ( pool->first != NULL ) {// 从队头取任务进行执行task_t *t = pool->first;pool->first = t->next;// 防止run函数执行的时间太长condition_unlock(&pool->ready);t->run(t->arg);condition_lock(&pool->ready);free(t);}// 等待到线程池销毁通知,并且任务都执行完毕if ( pool->quit == 1 && pool->first == NULL ) {pool->counter--;if ( pool->counter == 0 )condition_signal(&pool->ready);// 跳出循环之前,要记得解锁condition_unlock(&pool->ready);break;}// 超时处理if ( timeout == 1 && pool->first == NULL ) {pool->counter--;condition_unlock(&pool->ready);break;}condition_unlock(&pool->ready);}}void threadpool_add_task(threadpool_t *pool, void *(*run)(void*), void *arg){task_t *newtask = malloc(sizeof(task_t));newtask->run = run;newtask->arg = arg;newtask->next = NULL;condition_lock(&pool->ready);if ( pool->first == NULL )pool->first = newtask;elsepool->last->next = newtask;pool->last = newtask;if ( pool->idle > 0 ) {condition_signal(&pool->ready);} else if ( pool->counter < pool->max_threads ) {pthread_t tid;pthread_create(&tid, NULL, route, pool);pool->counter++;}condition_unlock(&pool->ready);}void threadpool_destroy(threadpool_t *pool){if ( pool->quit == 1 )return;condition_lock(&pool->ready);pool->quit = 1;if ( pool->counter > 0 ) {if ( pool->idle > 0 ) condition_broadcast(&pool->ready);// 如果发通知时有线程在工作,通知就丢失// 所以需要最后一个线程销毁时,给这个地方发送通知while ( pool->counter > 0 )condition_wait(&pool->ready);}condition_unlock(&pool->ready);condition_destroy(&pool->ready);}

4、测试代码

#include "threadpool.h"#include <stdio.h>void *mytask(void *arg){printf("thread %#X working on %d\n", pthread_self(), (int)arg);sleep(1);}int main( void ){threadpool_t pool;threadpool_init(&pool, 3);int i;for (i=0; i<10; i++) {dd_tathreadpool_ask(&pool, mytask, (void*)i);}//sleep(15);threadpool_destroy(&pool);}