|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
系统安全相关命令:passwd、su、umask、chgrp、chmod、chown、chattr、sudo、pswho
1、线程池概述
线程池是一种多线程处置情势,处置过程当中将义务增加到行列,然后在创立线程后主动启动这些义务。线程池线程都是背景线
程。每一个线程都利用默许的仓库巨细,以默许的优先级运转,并处于多线程单位中。假如某个线程在托管代码中余暇(如正在守候
某个事务),则线程池将拔出另外一个帮助线程来使一切处置器坚持忙碌。假如一切线程池线程都一直坚持忙碌,但行列中包括挂起
的事情,则线程池将在一段工夫后创立另外一个帮助线程但线程的数量永久不会凌驾最年夜值。凌驾最年夜值的线程能够列队,但他们
要比及其他线程完成后才启动。使用程序能够有多个线程,这些线程在休眠形态中必要泯灭大批工夫来守候事务产生。其他线程
大概进入眠眠形态,而且仅按期被叫醒以轮循变动或更新形态信息,然后再次进进休眠形态。为了简化对这些线程的办理,为每
个历程供应了一个线程池,一个线程池有多少个守候操纵形态,当一个守候操纵完成时,线程池中的帮助线程会实行回调函数。
线程池中的线程由体系办理,程序员不必要吃力于线程办理,能够会合精神处置使用程序义务。
利用线程池的优点:
1、削减在创立和烧毁线程上所花的工夫和体系资本的开支;
2、如不利用线程池,有大概形成体系创立大批线程而招致损耗完体系内存和”过分切换”。
在甚么情形下利用线程池:
1、单个义务处置的工夫对照短;
2、将需处置的义务的数目年夜。
在甚么情形下不利用线程池线程:
1、假如必要使一个义务具有特定优先级;
2、假如具有大概会长工夫运转(并因而堵塞其他义务)的义务;
3、假如必要将线程安排到单线程单位中(线程池中的线程均处于多线程单位中);
4、假如必要永世标识来标识和把持线程,好比想利用公用线程来停止该线程,将其挂起或按称号发明它。
2、线程池程序
main.c- #include<stdio.h>#include<unistd.h>#include"thread_pool.h"/**********************************************************************功效:义务处置函数*参数:无*前往值:NULL*********************************************************************/void*task_test(void*arg){ printf("/t/tworkingontask%d/n",(int)arg); sleep(1);/*歇息一秒,延伸义务的实行工夫*/ returnNULL;}intmain(intargc,char*argv[]){pool_tpool; inti=0; pool_init(&pool,2);//初始化线程池 sleep(1); for(i=0;i<5;i++){sleep(1);pool_add_task(&pool,task_test,(void*)i);//向线程池中增加一个义务 } sleep(4); pool_uninit(&pool);//烧毁线程池 return0;}
复制代码 thread_pool.c- #include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<assert.h>#include"thread_pool.h"staticvoid*pool_thread_server(void*arg);/**********************************************************************功效:初始化线程池布局体并创立线程*参数:pool:线程池句柄*threads_limit:线程池中线程的数目*前往值: 无*********************************************************************/voidpool_init(pool_t*pool,intthreads_limit){ pool->threads_limit=threads_limit; pool->queue_head=NULL; pool->task_in_queue=0; pool->destroy_flag=0; /*创立寄存线程ID的空间*/ pool->threadid=(pthread_t*)calloc(threads_limit,sizeof(pthread_t)); inti=0; /*初始化互斥锁和前提变量*/ pthread_mutex_init(&(pool->queue_lock),NULL); pthread_cond_init(&(pool->queue_ready),NULL); /*轮回创立threads_limit个线程*/ for(i=0;i<threads_limit;i++){pthread_create(&(pool->threadid[i]),NULL,pool_thread_server,pool); } return;}/**********************************************************************功效:烧毁线程池,守候行列中的义务不会再被实行,*可是正在运转的线程会一向,把义务运转完后再加入*参数:线程池句柄*前往值:乐成:0,失利非0*********************************************************************/intpool_uninit(pool_t*pool){ pool_task*head=NULL; inti;pthread_mutex_lock(&(pool->queue_lock)); if(pool->destroy_flag)/*避免两次挪用*/return-1; pool->destroy_flag=1; pthread_mutex_unlock(&(pool->queue_lock)); /*叫醒一切守候线程,线程池要烧毁了*/ pthread_cond_broadcast(&(pool->queue_ready)); /*堵塞守候线程加入,不然就成僵尸了*/ for(i=0;i<pool->threads_limit;i++)pthread_join(pool->threadid[i],NULL); free(pool->threadid); /*烧毁守候行列*/ pthread_mutex_lock(&(pool->queue_lock)); while(pool->queue_head!=NULL){head=pool->queue_head;pool->queue_head=pool->queue_head->next;free(head); } pthread_mutex_unlock(&(pool->queue_lock)); /*前提变量和互斥量也别忘了烧毁*/ pthread_mutex_destroy(&(pool->queue_lock)); pthread_cond_destroy(&(pool->queue_ready)); return0;}/**********************************************************************功效:向义务行列中增加一个义务*参数:pool:线程池句柄*process:义务处置函数*arg:义务参数*前往值: 无*********************************************************************/staticvoidenqueue_task(pool_t*pool,pool_task_fprocess,void*arg){ pool_task*task=NULL; pool_task*member=NULL;pthread_mutex_lock(&(pool->queue_lock));if(pool->task_in_queue>=pool->threads_limit){printf("task_in_queue>threads_limit!/n");pthread_mutex_unlock(&(pool->queue_lock));return; }task=(pool_task*)calloc(1,sizeof(pool_task)); assert(task!=NULL); task->process=process; task->arg=arg; task->next=NULL; pool->task_in_queue++; member=pool->queue_head; if(member!=NULL){while(member->next!=NULL) /*将义务到场就任务链连的最初地位.*/member=member->next;member->next=task; }else{pool->queue_head=task; /*假如是第一个义务的话,就指向头*/ } printf("/ttasks%d/n",pool->task_in_queue); /*守候行列中有义务了,叫醒一个守候线程*/ pthread_cond_signal(&(pool->queue_ready)); pthread_mutex_unlock(&(pool->queue_lock));}/**********************************************************************功效:从义务行列中掏出一个义务*参数:线程池句柄*前往值: 义务句柄*********************************************************************/staticpool_task*dequeue_task(pool_t*pool){ pool_task*task=NULL;pthread_mutex_lock(&(pool->queue_lock)); /*判别线程池是不是要烧毁了*/ if(pool->destroy_flag){pthread_mutex_unlock(&(pool->queue_lock));printf("thread0x%lxwillbedestroyed/n",pthread_self());pthread_exit(NULL); } /*假如守候行列为0而且不烧毁线程池,则处于堵塞形态*/ if(pool->task_in_queue==0){while((pool->task_in_queue==0)&&(!pool->destroy_flag)){printf("thread0x%lxisleisure/n",pthread_self());/*注重:pthread_cond_wait是一个原子操纵,守候前会解锁,叫醒后会加锁*/pthread_cond_wait(&(pool->queue_ready),&(pool->queue_lock));} }else{/*守候行列长度减往1,并掏出行列中的第一个元素*/pool->task_in_queue--;task=pool->queue_head;pool->queue_head=task->next;printf("thread0x%lxreceivedatask/n",pthread_self()); } pthread_mutex_unlock(&(pool->queue_lock)); returntask;}/**********************************************************************功效:向线程池中增加一个义务*参数:pool:线程池句柄*process:义务处置函数*arg:义务参数*前往值: 0*********************************************************************/intpool_add_task(pool_t*pool,pool_task_fprocess,void*arg){ enqueue_task(pool,process,arg); return0;}/**********************************************************************功效:线程池服务程序*参数:略*前往值:略*********************************************************************/staticvoid*pool_thread_server(void*arg){ pool_t*pool=NULL;pool=(pool_t*)arg; while(1){pool_task*task=NULL;task=dequeue_task(pool);/*挪用回调函数,实行义务*/if(task!=NULL){printf("thread0x%lxisbusy/n",pthread_self());task->process(task->arg);free(task);task=NULL;} } /*这一句应当是不成达的*/ pthread_exit(NULL);returnNULL;}
复制代码 thread_pool.h- #ifndef__THREAD_POOL_H__#define__THREAD_POOL_H__#include<pthread.h>/**********************************************************************义务回调函数,也可依据必要自行修正*********************************************************************/typedefvoid*(*pool_task_f)(void*arg);/**********************************************************************义务句柄*********************************************************************/typedefstruct_task{ pool_task_fprocess;/*回调函数,义务运转时会挪用此函数,注重也可声明成别的情势*/ void*arg;/*回调函数的参数*/ struct_task*next;}pool_task;/**********************************************************************线程池句柄*********************************************************************/typedefstruct{ pthread_t*threadid;/*线程号*/ intthreads_limit;/*线程池中同意的举动线程数量*/ intdestroy_flag;/*是不是烧毁线程池,0烧毁,1不烧毁*/ pool_task*queue_head;/*链表布局,线程池中一切守候义务*/ inttask_in_queue;/*以后守候行列的义务数量*/ pthread_mutex_tqueue_lock; /*锁*/ pthread_cond_tqueue_ready; /*前提变量*/}pool_t;/**********************************************************************功效:初始化线程池布局体并创立线程*参数:pool:线程池句柄*threads_limit:线程池中线程的数目*前往值: 无*********************************************************************/voidpool_init(pool_t*pool,intthreads_limit);/**********************************************************************功效:烧毁线程池,守候行列中的义务不会再被实行,*可是正在运转的线程会一向,把义务运转完后再加入*参数:线程池句柄*前往值: 乐成:0,失利非0*********************************************************************/intpool_uninit(pool_t*pool);/**********************************************************************功效:向线程池中增加一个义务*参数:pool:线程池句柄*process:义务处置函数*arg:义务参数*前往值: 0*********************************************************************/intpool_add_task(pool_t*pool,pool_task_fprocess,void*arg);#endif
复制代码 </p>
如果你让他去用linux搭建一个web服务器,做一个linux网关,他就什么都不会了.他们把时间都浪费在了版本的转换上了. |
|