线程池pthread-pool
原文地址:线程池pthread-pool – 无敌牛
欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等
分享一个线程池库,点击上边的按钮下载。源代码在 https://sourceforge.net/projects/pthread-pool/ ,编译时报错,改了几行代码。
第一步,解压: tar pzxvf pthread-pool.tar.gz,进入工作目录: cd pthread-pool-0.0.2
第二步,编译,执行里边的脚本即可: bash autocompile.sh 。
第三步,安装,执行命令:make install。动态库libpthreadpool.so会自动安装到 /usr/local/lib 目录,头文件则在 /usr/local/include 目录。编译的时候可以指定 头文件和so库的地址;运行的时候如果找不到 so 库,可以在 /etc/ld.so.conf.d/ 目录下随便加一个 xxx.conf的文件,里边内容是 /usr/local/lib/ ,然后执行 ldconfig,重新加载动态库查找路径。
以下是一个应用示例:
// 编译 gcc tptp.c -lpthreadpool -Wall
#include <stdio.h>
#include <stdlib.h>
#include <pthread_pool.h>
#include <unistd.h>
#include <string.h>
// 任务参数
typedef struct _arg_data_t {
int seed ;
int task_id ;
} arg_data_t ;
// 任务返回值
typedef struct _rtn_t {
int square ;
} rtn_t ;
// 任务执行函数
void * task_routine(void * args) {
static int cnt = 0 ;
printf("============== task_routine run cnt [%d] ===============\n", ++cnt ) ;
// 获取参数
arg_data_t * arg_data = (arg_data_t *)args ;
// 运算:返回的结果
rtn_t * rtn = (rtn_t * )calloc(1, sizeof(rtn_t)) ;
rtn->square = arg_data->seed * arg_data->seed ;
// 等待一下,看一下输出顺序
sleep(2) ;
return rtn;
}
#define WORKERNUM 3
#define TASKNUM 7
int main() {
int i = 0 ;
int ret = 0 ;
// 1、初始化 线程池 pool
pthread_pool_t pool ;
pthread_pool_create(&pool, NULL) ;
// 2、初始化 worker
pthread_pool_worker_t worker[WORKERNUM] ;
memset(&worker, 0x00, sizeof(worker)) ;
for(i=0 ; i<WORKERNUM ; ++i ) {
pthread_pool_worker_init(&worker[i], &pool, NULL) ;
}
// 3、任务参数初始化
arg_data_t * arg_data = NULL ;
pthread_pool_task_t * task = NULL ;
for(i=0 ; i<TASKNUM; ++i ) {
task = (pthread_pool_task_t *)calloc(1, sizeof(pthread_pool_task_t)) ;
arg_data = (arg_data_t *)calloc(1, sizeof(arg_data_t)) ;
arg_data->seed = 2+i ;
arg_data->task_id = i ;
// 4、设置任务参数和调用的函数。
// 如果有worker空闲,则唤醒一个worker并执行task_routine
ret = pthread_pool_task_init(task, &pool, &task_routine, arg_data) ;
printf("task [%d] init, ret [%d]\n", i, ret ) ;
}
rtn_t * rtn = NULL ;
for(i=0 ; i<TASKNUM; ) {
// 5、尝试获取任务结果
ret = pthread_pool_tryjoin(&pool, &task) ;
if(ret == 0) { // 获取到一个已完成的任务
pthread_pool_task_getretval(task, (void**)&rtn) ;
pthread_pool_task_getarg(task, (void**)&arg_data) ;
printf("\nresult :\ttask_id [%d]\tseed [%d]\tsquare [%d]\n", arg_data->task_id, arg_data->seed, rtn->square) ;
// 6、释放申请的空间
free(arg_data) ;
free(rtn) ;
free(task) ;
++i ;
} else {
sleep(1) ;
}
}
pthread_pool_wait(&pool) ; // 等待线程全部完成 --由于上两步已经等待了任务,此处已忽略。如果是异步获取结果,则需要等待任务完成。
// 7、销毁worker
for(i=0 ; i<WORKERNUM ; ++i ) {
pthread_pool_worker_destroy(&worker[i], &pool) ;
}
// 8、销毁pool
pthread_pool_destroy(&pool) ;
return 0 ;
}
测试结果: