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

【转载】实 现一个简单的linux线程池

发布时间:2022-12-16 12:45:33 所属栏目:Linux 来源:
导读:  原网址:

  线程池:简单地说,线程池 就是预先创建好一批线程线程池linux,方便、快速地处理收到的业务。比起传统的到来一个任务,即时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率
  原网址:
 
  线程池:简单地说,线程池 就是预先创建好一批线程线程池linux,方便、快速地处理收到的业务。比起传统的到来一个任务,即时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率更高。
 
  在linux中,使用的是posix线程库,首先介绍几个常用的函数:
 
  1 线程的创建和取消函数
 
  pthread_create
 
  创建线程
 
  pthread_join
 
  合并线程
 
  pthread_cancel
 
  取消线程
 
  2 线程同步函数
 
  pthread_mutex_lock
 
  pthread_mutex_unlock
 
  pthread_cond_signal
 
  pthread_cond_wait
 
  关于函数的详细说明,参考man手册
 
  线程池的实现:
 
  线程池的实现主要分为三部分,线程的创建、添加任务到线程池中、工作线程从任务队列中取出任务进行处理。
 
  主要有两个类来实现,CTask,CThreadPool
 
  /**
 
  执行任务的类,设置任务数据并执行
 
  **/
 
  class CTask
 
  {
 
  protected:
 
  string m_strTaskName; //任务的名称
 
  void* m_ptrData; //要执行的任务的具体数据
 
  public:
 
  CTask(){}
 
  CTask(string taskName)
 
  {
 
  this->m_strTaskName = taskName;
 
  m_ptrData = NULL;
 
  }
 
  virtual int Run()= 0;
 
  void SetData(void* data); //设置任务数据
 
  };
 
  任务类是个虚类,所有的任务要从CTask类中继承 ,实现run接口,run接口中需要实现的就是具体解析任务的逻辑。m_ptrData是指向任务数据的指针,可以是简单数据类型,也可以是自定义的复杂数据类型。
 
  线程池类
 
  /**
 
  线程池
 
  **/
 
  class CThreadPool
 
  {
 
  private:
 
  vector m_vecTaskList; //任务列表
 
  int m_iThreadNum; //线程池中启动的线程数
 
  static vector
 
  m_vecIdleThread; //当前空闲的线程集合
 
  static vector
 
  m_vecBusyThread; //当前正在执行的线程集合
 
  static pthread_mutex_t m_pthreadMutex; //线程同步锁
 
  static pthread_cond_t m_pthreadCond; //线程同步的条件变量
 
  protected:
 
  static void* ThreadFunc(void * threadData); //新线程的线程函数
 
  static int MoveToIdle(pthread_t tid); //线程执行结束后,把自己放入到空闲线程中
 
  static int MoveToBusy(pthread_t tid); //移入到忙碌线程中去
 
  int Create(); //创建所有的线程
 
  public:
 
  CThreadPool(int threadNum);
 
  int AddTask(CTask *task); //把任务添加到线程池中
 
  int StopAll();
 
  };
 
  当线程池对象创建后,启动一批线程,并把所有的线程放入空闲列表中,当有任务到达时,某一个线程取出任务并进行处理。
 
  线程之间的同步用线程锁和条件变量。
 
  这个类的对外接口有两个:
 
  AddTask函数把任务添加到线程池的任务列表中,并通知线程进行处理。当任务到到时,把任务放入m_vecTaskList任务列表中,并用pthread_cond_signal唤醒一个线程进行处理。
 
  StopAll函数停止所有的线程
 
  ************************************************
 
  代码:
 
  ××××××××××××××××××××CThread.h
 
  #ifndef __CTHREAD
 
  #define __CTHREAD
 
  #include
 
  #include
 
  #include
 
  using namespace std;
 
  /**
 
  执行任务的类,设置任务数据并执行
 
  **/
 
  class CTask
 
  {
 
  protected:
 
  string m_strTaskName; //任务的名称
 
  void* m_ptrData; //要执行的任务的具体数据
 
  public:
 
  CTask(){}
 
  CTask(string taskName)
 
  {
 
  this->m_strTaskName = taskName;
 
  m_ptrData = NULL;
 
  }
 
  virtual int Run()= 0;
 
  void SetData(void* data); //设置任务数据
 
  };
 
  /**
 
  线程池
 
  **/
 
  class CThreadPool
 
  {
 
  private:
 
  vector m_vecTaskList; //任务列表
 
  int m_iThreadNum; //线程池中启动的线程数
 
  static vector
 
  m_vecIdleThread; //当前空闲的线程集合
 
  static vector
 
  m_vecBusyThread; //当前正在执行的线程集合
 
  static pthread_mutex_t m_pthreadMutex; //线程同步锁
 
  static pthread_cond_t m_pthreadCond; //线程同步的条件变量
 
  protected:
 
  static void* ThreadFunc(void * threadData); //新线程的线程函数
 
  static int MoveToIdle(pthread_t tid); //线程执行结束后,把自己放入到空闲线程中
 
  static int MoveToBusy(pthread_t tid); //移入到忙碌线程中去
 
  int Create(); //创建所有的线程
 
  public:
 
  CThreadPool(int threadNum);
 
  int AddTask(CTask *task); //把任务添加到线程池中
 
  int StopAll();
 
  };
 
  #endif
 
  类的实现为:
 
  ××××××××××××××××××××CThread.cpp
 
  #include "CThread.h"
 
  #include
 
  #include
 
  using namespace std;
 
  void CTask::SetData(void * data)
 
  {
 
  m_ptrData = data;
 
  }
 
  vector
 
  CThreadPool::m_vecBusyThread;
 
  vector
 
  CThreadPool::m_vecIdleThread;
 
  pthread_mutex_t CThreadPool::m_pthreadMutex = PTHREAD_MUTEX_INITIALIZER;
 
  pthread_cond_t CThreadPool::m_pthreadCond = PTHREAD_COND_INITIALIZER;
 
  CThreadPool::CThreadPool(int threadNum)
 
  {
 
  this->m_iThreadNum = threadNum;
 
  Create();
 
  }
 
  int CThreadPool::MoveToIdle(pthread_t tid)
 
  {
 
  vector
 
  ::iterator busyIter = m_vecBusyThread.begin();
 
  while(busyIter != m_vecBusyThread.end())
 
  {
 
  if(tid == *busyIter)
 
  {
 
  break;
 
  }
 
  busyIter++;
 
  }
 
  m_vecBusyThread.erase(busyIter);
 
  m_vecIdleThread.push_back(tid);
 
  return 0;
 
  }
 
  int CThreadPool::MoveToBusy(pthread_t tid)
 
  {
 
  vector
 
  ::iterator idleIter = m_vecIdleThread.begin();
 
  while(idleIter != m_vecIdleThread.end())
 
  {
 
  if(tid == *idleIter)
 
  {
 
  break;
 
  }
 
  idleIter++;
 
  }
 
  m_vecIdleThread.erase(idleIter);
 
  m_vecBusyThread.push_back(tid);
 
  return 0;
 
  }
 
  void* CThreadPool::ThreadFunc(void * threadData)
 
  {
 
  pthread_t tid = pthread_self();
 
  while(1)
 
  {
 
  pthread_mutex_lock(&m_pthreadMutex);
 
  pthread_cond_wait(&m_pthreadCond,&m_pthreadMutex);
 
  cout
 

(编辑:财气旺网 - 财气网)

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