加入收藏 | 设为首页 | 会员中心 | 我要投稿 我爱制作网_沈阳站长网 (https://www.024zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

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);
  }
 

(编辑:我爱制作网_沈阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!