C线程池
时间:2023-04-06 04:57:17
Linux
标题:C线程池分类:[C++]标签:[编程语言]日期:2021/06/28作者:hackett
微信公众号:超时猿 C线程池1.准备查看线程相关接口函数:线程创建intpthread_create(pthread_tthread,constpthread_attr_tattr,void(start_routine)(void),voidarg);参数说明:1、参数thread指向存放新创建线程的线程ID的地址。2、attr参数用于自定义各种线程属性。可以临时设置为NULL,创建一个默认属性的线程。3、start_routine是一个函数指针,这个函数的返回类型是void,形参也是void。新创建的线程从start_routine函数的地址开始运行。此函数只有一个无类型指针参数arg。如果需要给start_routine函数传递的参数不止一个,那么就需要将这些参数放入一个结构体中,然后将这个结构体的地址作为arg参数传入。返回值:线程创建成功返回0,失败返回其他值。线程等待intpthread_join(pthread_tthread,void**retval);参数说明:调用该函数的线程将被阻塞,直到指定线程调用pthread_exit。如果对线程的返回值不感兴趣,可以将retval设置为NULL。在这种情况下,调用pthread_join函数会等待指定线程终止,但不会获取线程的终止状态。线程取消intpthread_cancel(pthread_tthread);参数说明:thread为线程id设置线程取消信号intpthread_setcancelstate(intstate,int*oldstate);PTHREAD_CANCEL_ENABLE:线程可以被取消。这是所有新线程(包括初始线程)的默认取消状态。线程的可取消类型决定可取消线程何时响应取消请求。PTHREAD_CANCEL_DISABLE:线程不能被取消。如果收到取消请求,它将阻塞直到启用可取消。清理线程voidpthread_cleanup_push(void(*rtn)(void*),void*arg);参数说明:void(*rtn)(void*):线程清理函数arg传递的参数激活所有等待线程pthread_cond_broadcast(pthread_cond_t*cond);查看mutex相关接口函数:createamutexintpthread_mutex_init(pthread_mutex_trestrictmutex,constpthread_mutexattr_t限制属性);参数说明:1、使用互斥锁之前,需要先定义一个互斥锁(全局变量),定义一个互斥锁独占锁对象的形式为:pthread_mutex_tlock;2、mutex是指向需要初始化的mutex的指针;3、参数attr指定了新创建的mutex的属性。如果参数attr为NULL,则使用默认的mutex属性,默认属性为fastmutex。销毁互斥体intpthread_mutex_destroy(pthread_mutex_t*mutex);参数说明:mutex为需要销毁的互斥锁;锁定互斥锁intpthread_mutex_lock(pthread_mutex_t*mutex);参数说明:mutex为需要加锁的互斥量;Mutexintpthread_mutex_unlock(pthread_mutex_t*mute);参数说明:mutex为需要解锁的互斥量;查看条件变量的相关接口函数:条件变量是一种利用线程间共享的全局变量进行同步的机制,主要包括两个动作:一个线程等待“条件变量的条件成立”并挂起;另一个线程使“有条件的”(发出条件成立的信号)。为了防止竞争条件,条件变量的使用总是与互斥锁结合使用。初始化条件变量intpthread_cond_init(pthread_cond_tcond,pthread_condattr_tcond_attr);参数说明:1.cond是初始化的条件变量,是指向结构体pthread_cond_t的指针;2.cond_attr是cond_attr是指向结构体pthread_condattr_t的指针;销毁条件变量intpthread_cond_destroy(pthread_cond_t*cond);参数说明:cond为销毁的条件变量;等待条件变量成立2.创建数据结构task结构structtask{void*(*task)(void*arg);/*任务需要执行的函数*/void*arg;/*执行函数参数*/structtask*next;/*下一个任务的地址*/};线程池结构typedefstructthread_pool{pthread_mutex_tlock;pthread_cond_t条件;结构任务*任务列表;/*链表结构,线程池中所有等待任务*/pthread_t*tids;/*存储线程id的指针*/unsignedwaiting_tasks;/*当前等待的任务数*/unsignedactive_threads;/*线程池中的线程数*/boolshutdown;/*是否销毁线程池*/}thread_pool;3.线程池函数初始化线程池/**@description:初始化线程池*@param{thread_pool*}pool:线程池结构指针{unsignedint}max_thread_num:创建多个线程*@return:falsefailedtruesuccessful*/boolinit_pool(thread_pool*pool,unsignedintthreads_number){pthread_mutex_init(&pool->lock,NULL);/*初始化线程锁*/pthread_cond_init(&pool->cond,NULL);/*初始化条件变量*/pool->shutdown=false;pool->task_list=malloc(sizeof(structtask));pool->tids=malloc(sizeof(pthread_t)*MAX_ACTIVE_THREADS);if(pool->task_list==NULL||pool->tids==NULL){perror("分配内存错误");返回假;}pool->task_list->next=NULL;池->waiting_tasks=0;池->active_threads=threads_number;诠释我;for(i=0;i
active_threads;i++){if(pthread_create(&((pool->tids)[i]),NULL,routine,(void*)pool)!=0){perror(“创建线程错误”);返回假;}}returntrue;}添加任务到线程池/**@description:向线程池添加任务*@param{thread_pool*}pool:线程池结构体指针{void*(void*arg)}(*task):线程的回复数{void*}arg:传入的参数*@return:false失败true成功*/booladd_task(thread_pool*pool,void*(*task)(void*arg),void*arg){structtask*new_task=malloc(sizeof(structtask));if(new_task==NULL){perror("分配内存错误");返回假;}new_task->task=task;new_task->arg=arg;new_task->next=NULL;pthread_mutex_lock(&pool->lock);如果(池->waiting_tasks>=MAX_WAITING_TASKS){pthread_mutex_unlock(&pool->lock);fprintf(stderr,"任务太多。\n");免费(新任务);返回假;}structtask*tmp=pool->task_list;while(tmp->next!=NULL)tmp=tmp->next;tmp->next=new_task;池->waiting_tasks++;pthread_mutex_unlock(&pool->lock);pthread_cond_signal(&pool->cond);returntrue;}添加线程到线程池/**@description:添加线程到线程池*@param{thread_pool*}pool:线程池结构体指针{unsignedint}additional_threads:添加的线程数*@return:返回成功数线程数*/intadd_thread(thread_pool*pool,unsignedintadditional_threads){if(additional_threads==0)return0;unsignedinttotal_threads=pool->active_threads+additional_threads;inti,actual_increment=0;for(i=pool->active_threads;itids)[i]),NULL,routine,(void*)pool)!=0复制代码){perror("添加线程错误");如果(实际增量==0)返回-1;休息;}实际增量++;}pool->active_threads+=actual_increment;returnactual_increment;}线程回调处理函数/**@description:回调处理函数*@param{void*}arg:传入参数*@return:none*/voidhandler(void*arg){pthread_mutex_unlock((pthread_mutex_t*)arg);}/**@description:线程的回调处理函数*@param{void*}arg:传入的参数*@return:无*/void*routine(void*arg){thread_pool*pool=(thread_pool*)arg;结构任务*p;while(1){pthread_cleanup_push(handler,(void*)&pool->lock);pthread_mutex_lock(&pool->lock);while(pool->waiting_tasks==0&&!pool->shutdown){pthread_cond_wait(&pool->cond,&pool->lock);}if(pool->waiting_tasks==0&&pool->shutdown==true){pthread_mutex_unlock(&pool->lock);pthread_exit(NULL);}p=pool->task_list->next;pool->task_list->next=p->next;池->waiting_tasks--;pthread_mutex_unlock(&pool->lock);pthread_cleanup_pop(0);pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);(p->任务)(p->arg);pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);免费(p);}pthread_exit(NULL);}取消线程池中的线程/**@description:取消线程池中的线程*@param{thread_pool*}pool:线程池结构体指针{nsignedint}removing_threads:取消线程数*@return:失败时返回-1*/intremove_thread(thread_pool*pool,unsignedintremoving_threads){if(removing_threads==0)returnpool->active_threads;intremain_threads=pool->active_threads-removing_threads;remain_threads=remain_threads>0?剩余线程数:1;诠释我;for(i=pool->active_threads-1;i>remain_threads-1;i--){errno=pthread_cancel(pool->tids[i]);如果(错误号!=0)中断;}if(i==pool->active_threads-1)返回-1;else{pool->active_threads=i+1;返回i+1;}}销毁线程池/**@description:销毁线程池*@param{thread_pool*}pool:线程池结构体指针*@return:成功则返回true*/booldestroy_pool(thread_pool*pool){pool->关机=真;pthread_cond_broadcast(&pool->cond);诠释我;for(i=0;iactive_threads;i++){errno=pthread_join(pool->tids[i],NULL);if(errno!=0){printf("jointids[%d]错误:%s\n",i,strerror(errno));}elseprintf("[%u]加入\n",(unsigned)pool->tids[i]);}免费(池->任务列表);免费(池->tids);免费(池);returntrue;}4.完整代码由于代码篇幅就不贴出来了,如果需要在微信回复【话题】公众号,可以获取链接下载使用:进入linux下文件夹,执行make生成可执行文件test,执行即可。如果觉得文章还不错,可以给个“三连”我是加班猿,下期见