Linux线程池实 现之改进
发布时间:2022-12-01 13:12:32 所属栏目:Linux 来源:
导读: 上一篇写到实现了一个线程池,但是那个线程池的任务回调函数却用到了四个变量之多,自己又仔细思考了一下线程池linux,这样做只是为了把任务函数的参数传进行去而以,这样做真的是多此一举,既然参数据设定为voi
|
上一篇写到实现了一个线程池,但是那个线程池的任务回调函数却用到了四个变量之多,自己又仔细思考了一下线程池linux,这样做只是为了把任务函数的参数传进行去而以,这样做真的是多此一举,既然参数据设定为void *类型的,那就完全可以传进行所有类型的参数,完全可以将参数组成一个结构体, 将结构体的指针传给回调函数。 改进代码如下: ThreadWorker结构体改进 typedef struct worker{ void (*process)(void * arg); void * arg; struct worker *next; } ThreadWorker; AddWorker方法改进,只有一个参数: void ThreadPool::AddWorker(void (*process)(void * ), void * arg) { ThreadWorker * new_worker = (ThreadWorker *)malloc(sizeof(ThreadWorker)); new_worker->process = process; new_worker->arg = arg; new_worker->next = NULL; pthread_mutex_lock(&m_queueLock); ThreadWorker * wk = m_workerHead; if (wk == NULL) { m_workerHead = new_worker; }else { while(wk->next != NULL) wk = wk->next; wk->next = new_worker; } assert(m_workerHead != NULL); m_workerSize++; pthread_mutex_unlock(&m_queueLock); pthread_cond_signal(&m_queueReady); return; } thread_loop函数中的改进: void * ThreadPool::__thread_loop(void * arg) { ...... (*(worker->process))(worker->arg); free(worker); worker = NULL; } return NULL; } 调用示例: #include #include #include #include void do_one_mesh(char * base, char * updated, char *input_name, char * output_path); void do_in_thread_pool(void * args); //参数结构体 typedef struct { char * output_path; const char * mesh_name; Regions base_regions; Regions updated_regions; } ThreadWorkerArgs; int main(int argc, char ** argv) { char * root_path = NULL; char * updated = NULL; char * base = NULL; char * input_name = NULL; char * output_path = NULL; bool one_mesh = false; int thread_num = 1; int c; while((c = getopt(argc, argv, "j::o::n::r::b::u::Oh")) != -1) { switch(c) { case 'j': thread_num = atoi(optarg); break; case 'r': root_path = optarg; break; case 'n': input_name = optarg; break; case 'O': one_mesh = true; break; case 'b': base = optarg; break; case 'u': updated = optarg; break; case 'o': output_path = optarg; break; case 'h': printf("参数说明:\n"); printf("-O后面不需要带参数,其他均需参数\n"); printf("参数一定要紧跟选项后面\n"); printf("例如:-b/home/data\n"); printf("-n: 数据文件名\n"); printf("-b: 基板版本号,如果带-O选项,那么就是基板数据所在的目录\n"); printf("-u: 差分版版本号,如果带-O选项,那么就是差分版数据所在的目录\n"); printf("-r: 数据根目录,当带-O选项是,该选项无用\n"); printf("-O: 带此选项为直接指定差分版与基板数据路径\n"); printf("-o: 需带参数,为结果输出目录\n"); return 0; case '?': fprintf(stderr, "please use [-O] [-n] [-b] [-u] -[i] options\n"); return -1; break; } } if (updated == NULL || base == NULL || input_name == NULL || output_path == NULL) { fprintf(stderr, "-n, -b, -o options can not be empty!\n"); return -1; } if (one_mesh) { do_one_mesh(base, updated, input_name, output_path); }else { int base_version = 0; int updated_version = 0; if (root_path == NULL) { fprintf(stderr, "-b options can not be empty!\n"); return -1; } if ((base_version = atoi(base)) == 0) { fprintf(stderr, "-b options must be an integer!\n"); return -1; } if ((updated_version = atoi(updated)) == 0) { fprintf(stderr, "-u options must be an integer!\n"); return -1; } std::map base_paths, updated_paths; AutoGetPreVersion(root_path, base_version, updated_version, base_paths, updated_paths); MeshRegions base_mesh_regions, updated_mesh_regions; LoadAll(input_name, base_paths, updated_paths, base_mesh_regions, updated_mesh_regions); int mesh_num = updated_mesh_regions.size(); ThreadPool * pool = new ThreadPool(thread_num); pool->ThreadPoolInit(); BOOST_FOREACH(MeshRegionsPair & pair, updated_mesh_regions) { ThreadWorkerArgs *arg = new ThreadWorkerArgs(); arg->mesh_name = pair.first.c_str(); arg->output_path = output_path; arg->base_regions = base_mesh_regions[pair.first]; arg->updated_regions = pair.second; pool->AddWorker(do_in_thread_pool, arg); } while (pool->GetWorkerNum() != 0) { double process = (mesh_num - pool->GetWorkerNum())/mesh_num * 100; //printf("\rprocessing: %f%%", process); sleep(1); } pool->ThreadPoolDestroy(); //printf("\rprocessing: 100%%\n"); return 0; } return 0; } void do_one_mesh(char * base, char * updated, char * input_name, char * output_path) { Regions base_regions; Regions updated_regions; Regions del; Regions add; LoadOne(base, updated, input_name, base_regions, updated_regions); DoOneDiff(base_regions, updated_regions, add, del); WriteOne(output_path, add, del); } //线程池任务回调函数,注意参数结构体的作用 void do_in_thread_pool(void * args) { ThreadWorkerArgs * wk_args = (ThreadWorkerArgs *)args; const char * mesh_name = wk_args->mesh_name; char * output_path = wk_args->output_path; Regions base_regions = wk_args->base_regions; Regions updated_regions = wk_args->updated_regions; Regions add; Regions del; printf("now doing mesh: %s\n", mesh_name); DoOneDiff(base_regions, updated_regions, add, del); printf("now writing result\n"); WriteByMesh(output_path, mesh_name, add, del); printf("mesh: %s has been done\n", mesh_name); } (编辑:我爱制作网_沈阳站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐


浙公网安备 33038102330576号