线程池技术个人理解以及c语言的简单实现 线程池实现原理

转载:http://blog.csdn.net/mxgsgtc/article/details/11694901

这几天闲来无事,网上无意中看到了关于线程池的东西,发现挺有意思的,找了挺多资料,研究一下,线程池技术,个人理解,线程池是个集合(概念上的,当然是线程的集合),假设这个集合中有3个线程A , B, C 这三个线程初始化的时候就是等待的状态,等待任务的到来,假设有任务1, 2, 3, 4, 5(任务处理的内容是一样的),线程池会怎么处理呢

①:A会处理1任务(任务其实就是函数),B会处理2任务,C处理3任务

②:当1任务结束之后,A会处理4任务;2任务结束后B会处理5任务,3任务结束后,C会等待(因为没有任务了)③:当所有任务处理完之后,A,B,C都会等待状态,等待新任务的到来上面陈述的是一般简单线程池的具体事例,那么如何实现,下面贴出代码(linux环境)

[cpp] view plaincopy

#include<stdio.h>

#include<stdlib.h>

#include<pthread.h>

#include<unistd.h>

#include<sys/types.h>

#include<assert.h>

#include<string.h>

typedefvoid*(*TaskFun)(void*arg);

typedefstruct_TskNode{

TaskFunTaskDmd;/*task节点任务处理函数*/

void*arg;/*传入任务处理函数的参数*/

struct_TskNode*pPre;/*前一个任务节点*/

struct_TskNode*pNext;/*后一个任务节点*/

}TskNode;/*队列节点*/

typedefstruct_tskQueueManage{

inttskCurWaitNum;/*当前任务队列的任务数量*/

struct_TskNode*pTskHead;/*当前任务队列的首节点*/
线程池技术个人理解以及c语言的简单实现 线程池实现原理

struct_TskNode*pTskTail;/*当前任务队列的尾节点*/

}TskQueueManage;/*任务队列描述符*/

typedefstruct_threadManage{

intthdMaxNum;/*线程池容纳最大线程数量*/

pthread_t*pth;/*线程指针*/

pthread_mutex_tmutex;/*线程锁*/

pthread_cond_tcond;/*线程条件变量*/

}ThreadManage;/*线程描述符*/

typedefstruct_thredPoolManage{

intshutFlag;/*线程池摧毁标识*/

ThreadManage*pThdManage;/*线程描述符指针*/

TskQueueManage*pTskQueueManage;/*任务队列描述符指针*/

}ThdPoolManage;/*线程池描述符*/

/*初始化,上述描述符*/

staticintmainDmdInit(intthdMaxNum);

/*线程的创建*/

staticvoidthdPoolCreat();

/*线程池中的线程启动后处理*/

staticvoidthreadCreatdmd();

/*任务添加*/

staticinttskAddDmd(TaskFunTaskDmd,void*arg);

/*线程池的销毁*/

staticvoidthdPoolDestroy();

/*线程池描述符指针*/

ThdPoolManage*pThdPoolManage=NULL;

staticintmainDmdInit(intthdMaxNum)

{

intflag=0;

/*线程池描述符的创建*/

pThdPoolManage=(ThdPoolManage*)malloc(sizeof(struct_thredPoolManage));

if(pThdPoolManage!=NULL){

/*线程描述符的创建*/

pThdPoolManage->pThdManage=(ThreadManage*)malloc(sizeof(struct_threadManage));

if(pThdPoolManage->pThdManage!=NULL){

/*线程互斥锁于条件变量的初始化*/

pthread_mutex_init(&(pThdPoolManage->pThdManage->mutex),NULL);

pthread_cond_init(&(pThdPoolManage->pThdManage->cond),NULL);

/*将线程池中允许的最大线程数赋值给线程池描述符成员*/

pThdPoolManage->pThdManage->thdMaxNum=thdMaxNum;

/*线程pthread_t的创建*/

pThdPoolManage->pThdManage->pth=(pthread_t*)malloc(thdMaxNum*sizeof(pthread_t));

if(pThdPoolManage->pThdManage->pth!=NULL){

/*工作队列描述符的创建*/

pThdPoolManage->pTskQueueManage=(TskQueueManage*)malloc(sizeof(struct_tskQueueManage));

if(pThdPoolManage->pTskQueueManage!=NULL){

/*初始队列工作描述符*/

pThdPoolManage->pTskQueueManage->tskCurWaitNum=0;

pThdPoolManage->pTskQueueManage->pTskHead=NULL;

pThdPoolManage->pTskQueueManage->pTskTail=NULL;

/*线程池中所有线程的创建*/

thdPoolCreat();

}else{

/*注意:如果malloc不成功,一定要free掉之前的malloc申请*/

free(pThdPoolManage->pThdManage->pth);

free(pThdPoolManage->pThdManage);

free(pThdPoolManage);

/*如果malloc失败,说明错误flag赋值为=1*/

flag=1;

printf("[%s]:[%d]Warning:failed.n",__func__,__LINE__);

}

}else{

free(pThdPoolManage->pThdManage);

free(pThdPoolManage);

flag=1;

printf("[%s]:[%d]Warning:failed.n",__func__,__LINE__);

}

}else{

free(pThdPoolManage);

flag=1;

printf("[%s]:[%d]Warning:failed.n",__func__,__LINE__);

}

}else{

flag=1;

printf("[%s]:[%d]Warning:failed.n",__func__,__LINE__);

}

returnflag;

}

staticvoidthdPoolCreat()

{

ThreadManage*pThreadManage=NULL;

intthdNum;

pThreadManage=pThdPoolManage->pThdManage;

for(thdNum=0;thdNum<pThreadManage->thdMaxNum;thdNum++){

pthread_create(&(pThreadManage->pth[thdNum]),NULL,(void*)threadCreatdmd,NULL);

}

}

staticvoidthreadCreatdmd(void*arg)

{

/*注意指针赋值之前要初始化为NULL,以免发生后续出现野指针的情况*/

TskQueueManage*pTskQueueManage=NULL;

ThreadManage*pThreadManage=NULL;

TskNode*pCurTsk=NULL;

printf("threadCreatdmd_creat_success:[ThreadId]=[%x]n",pthread_self());

pTskQueueManage=pThdPoolManage->pTskQueueManage;

pThreadManage=pThdPoolManage->pThdManage;

while(1){

/*注意,因为会创建很多个threadCreatdmd函数,由于每个函数都要访问临界代码:即对工作队列的操作,所以必须要枷锁

以保证每一个处理函数(threadCreatdmd),在访问工作队列的时候,此工作队列不会被其他的处理函数修改*/

pthread_mutex_lock(&(pThreadManage->mutex));

/*最开始创建线程池中的线程需要等待的两种情况,即,while循环条件成立的情况,1.线程池初始化时候(即没添加任务之前),2.

工作队列没有任务了(即任务都执行完了)*/

while((pTskQueueManage->tskCurWaitNum==0)&&(pThdPoolManage->shutFlag==0)){

printf("[ThreadId]=[%x]_waiting.........n",pthread_self());

/*这时此线程会在这里阻塞*/

pthread_cond_wait(&(pThreadManage->cond),&(pThreadManage->mutex));

}

if(pThdPoolManage->shutFlag==1){

pthread_mutex_unlock(&(pThreadManage->mutex));

printf("[ThreadId]=[%x]_exitn",pthread_self());

pthread_exit(NULL);

}

printf("[ThreadId]=[%x]_starting_work!!n",pthread_self());

assert(pTskQueueManage->tskCurWaitNum!=0);

assert(pTskQueueManage->pTskHead!=NULL);

(pTskQueueManage->tskCurWaitNum)--;

/*取工作队列头部节点*/

pCurTsk=pTskQueueManage->pTskHead;

/*取头之后,将新头赋给下个元素*/

pTskQueueManage->pTskHead=pTskQueueManage->pTskHead->pNext;

/*注意:如果最后一个元素这时候pTskQueueManage->pTskHead是空,空的话是没有pPre的*/

if(pTskQueueManage->pTskHead!=NULL){

pTskQueueManage->pTskHead->pPre=NULL;

}

pthread_mutex_unlock(&(pThreadManage->mutex));

/*执行头部任务节点的任务函数(即上面取出的节点)*/

(pCurTsk->TaskDmd)(pCurTsk->arg);

free(pCurTsk);

pCurTsk=NULL;

}

}

staticinttskAddDmd(TaskFunTaskDmd,void*arg)

{

TskNode*pTskNode=NULL;

TskQueueManage*pTskQueueManage=NULL;

ThreadManage*pThdManage=NULL;

intflag=0;

pTskQueueManage=pThdPoolManage->pTskQueueManage;

pThdManage=pThdPoolManage->pThdManage;

pthread_mutex_lock(&(pThdManage->mutex));

/*任务添加,创建一个工作节点*/

pTskNode=(TskNode*)malloc(sizeof(struct_TskNode));

if(pTskNode!=NULL){

/*将任务(函数赋值给节点)*/

pTskNode->TaskDmd=TaskDmd;

pTskNode->pNext=NULL;

/*赋值参数*/

pTskNode->arg=arg;

if(pTskQueueManage->tskCurWaitNum==0){

pTskQueueManage->pTskHead=pTskNode;

pTskQueueManage->pTskTail=pTskNode;

}else{

pTskQueueManage->pTskTail->pNext=pTskNode;

pTskNode->pPre=pTskQueueManage->pTskTail;

pTskQueueManage->pTskTail=pTskNode;

}

(pTskQueueManage->tskCurWaitNum)++;

}else{

flag=1;

printf("[%s]:[%d]Warning:failed.n",__func__,__LINE__);

}

pthread_mutex_unlock(&(pThdManage->mutex));

pthread_cond_signal(&(pThdManage->cond));

returnflag;

}

staticvoidthdPoolDestroy()

{

intthdNum;

pThdPoolManage->shutFlag=1;

TskQueueManage*pTskQueueManage=NULL;

ThreadManage*pThdManage=NULL;

TskNode*pTskNode=NULL;

pTskQueueManage=pThdPoolManage->pTskQueueManage;

pThdManage=pThdPoolManage->pThdManage;

pthread_cond_broadcast(&(pThdPoolManage->pThdManage->cond));

for(thdNum=0;thdNum<pThdManage->thdMaxNum;thdNum++){

pthread_join(pThdManage->pth[thdNum],NULL);

}

while(pTskQueueManage->pTskHead!=NULL){

pTskNode=pTskQueueManage->pTskHead;

pTskQueueManage->pTskHead=pTskQueueManage->pTskHead->pNext;

free(pTskNode);

}

pthread_mutex_destroy(&(pThdManage->mutex));

pthread_cond_destroy(&(pThdManage->cond));

free(pThdPoolManage->pThdManage->pth);

free(pThdPoolManage->pThdManage);

free(pThdPoolManage->pTskQueueManage);

free(pThdPoolManage);

pThdPoolManage=NULL;

}

voidTaskDmd(void*arg)

{

printf("[ThreadId]=[%x]workingontask[%d]n",pthread_self(),*((int*)arg));

sleep(1);

}

/*测试代码*/

intmain()

{

intflag;

inttaskAdd;

int*taskArg;

inttaskNum=10;

intthdMaxNum=3;

flag=mainDmdInit(thdMaxNum);

/*保险起见两秒,因为可能会造成添加任务在线程等待之前执行*/

sleep(2);

taskArg=(int*)malloc(sizeof(int)*taskNum);

memset(taskArg,0x00,sizeof(int)*taskNum);

if(flag!=1){

for(taskAdd=0;taskAdd<taskNum;taskAdd++){

taskArg[taskAdd]=taskAdd;

flag=tskAddDmd((void*)TaskDmd,&(taskArg[taskAdd]));

if(flag==1){

printf("jobAdderrorNum=[%d]n",taskAdd);

}else{

printf("jobAddsuccessNum=[%d]n",taskAdd);

}

}

}else{

printf("[%s]:[%d]Warning:failed.n",__func__,__LINE__);

}

sleep(10);

thdPoolDestroy();

return0;

}

  

爱华网本文地址 » http://www.aihuau.com/a/25101011/88228.html

更多阅读

C语言最重要的知识点复习资料

总体上必须清楚的:1)程序结构是三种:顺序结构、选择结构(分支结构)、循环结构。2)读程序都要从main()入口,然后从最上面顺序往下读(碰到循环做循环,碰到选择做选择),有且只有一个main函数。3)计算机的数据在电脑中保存是以二进制

单片机C语言教程二 转载 单片机c语言视频教程

第二课 初步认识51芯片上一课我们的第一个项目完成了,可能有懂C语言的朋友会说,"这和PC机上的C语言没有多大的区别呀"。的确没有太大的区别,C语言只是一种程序语言的统称,针对不同的处理器相关的C语言都会有一些细节的改变。编写

c语言的sound函数和delay函数的问题 delay函数

函数:void delay(uint i){while(i)i--;}这样的延迟设计很不好,因为受影响的因素太多。首先就是机器的CPU频率,快的CPU执行i--这句的机器时间短,慢的机器就很慢。其次是当前机器的负荷情况,负荷较重时,系统给当前进程分配的CPU时间少,执行这

声明:《线程池技术个人理解以及c语言的简单实现 线程池实现原理》为网友逍遥随风分享!如侵犯到您的合法权益请联系我们删除