• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > c++实现简单的线程池

c++实现简单的线程池

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c++线程池,队列线程池c++,c++线程池原理,c++创建线程,c++多线程等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

这是对pthread线程的一个简单应用

1.      实现了线程池的概念,线程可以重复使用。
2.      对信号量,互斥锁等进行封装,业务处理函数中只需写和业务相关的代码。
3.      移植性好。如果想把这个线程池代码应用到自己的实现中去,只要写自己的业务处理函数和改写工作队列数据的处理方法就可以了。

Sample代码主要包括一个主程序和两个线程实现类
ThreadTest.cpp:主程序
CThreadManager:线程管理Class,线程池的实现类
CThread:线程Class.

主程序实现方法。

1.      实现main函数和一个需要线程处理的业务函数(例子代码中业务函数是一个简单的计算函数Count)。在main函数中创建CThreadManager的实例,产生线程池。这个时候,把业务函数作为函数指针传到CThreadManager里面,最终会被线程调用。
2.      向工作队列中放入业务函数要处理的数据。
3.      设置信号量,唤醒线程。

// 线程要执行的函数
int Count(int nWork)
{
  int nResult = nWork * nWork;
  printf("count result is %d\n",nResult);
  return 0;
}
int main() {
  // 创建线程管理类的实例,把要执行的线程函数和最大线程数传进去
  CThreadManager* pManager = new CThreadManager(Count, 3);
  // 把要进行计算的数放到工作队列中
  pManager->PushWorkQue(5);
  pManager->PushWorkQue(20);
  // 设置信号量,唤醒线程
  pManager->PostSem();
  pManager->PostSem();
  // 等待子线程执行
  sleep(1);
  return 0;
}

</div>

CThreadManager实现的方法

1. 把信号量和互斥锁等封装成自己的函数
2. 在new方法里,循环调用CThread的new方法,启动一定数量(可设定)的线程,产生线程池。
3. 这些线程启动后,就会执行CThreadManager中的ManageFuction函数。这个函数是无限循环的,保证了线程在整个程序的生命周期中不销毁。
4. 在循环处理里面,第一行代码就是等待一个信号量,这个信号量是由主程序进行设置的,这个信号信号量如果没有被设置(代表暂时没有需要处理的工作),所有线程都在这里阻塞着。
4.      一旦信号量被设置,根据Linux线程调度机制,在阻塞的线程队列中,其中一个线程被唤醒,可以执行后面的代码。
5.      从工作队列中取出要进行处理的数据(使用互斥锁进行排他)
6.      通过函数指针调用main函数传过来的业务函数,处理数据。
7.      业务函数执行完之后,线程进入下一个循环,等待新的信号量。

class CThreadManager {
  friend void* ManageFuction(void*);
private:
  sem_t m_sem;  // 信号量
  pthread_mutex_t m_mutex; // 互斥锁
  queue<int> m_queWork; // 工作队列
  list<CThread*> m_lstThread; // 线程list
  int (*m_threadFuction)(int); //函数指针,指向main函数传过来的线程执行函数
public:
  CThreadManager(int (*threadFuction)(int), int nMaxThreadCnt);
  virtual ~CThreadManager();
  int WaitSem();
  int PostSem();
  int LockMutex();
  int UnlockMutex();
  void PushWorkQue(int nWork);
  int PopWorkQue();
  int RunThreadFunction(int nWork);
};
// 线程执行函数,它只是个壳子,处理信号量和互斥锁等,
// 最后调用main函数传过来的线程执行函数来实现业务处理
void* ManageFuction(void* argv)
{
  CThreadManager* pManager = (CThreadManager*)argv;
  // 进行无限循环(意味着线程是不销毁的,重复利用)
  while(true)
  {
    // 线程开启后,就在这里阻塞着,直到main函数设置了信号量
    pManager->WaitSem();
    printf("thread wakeup.\n");
    // 从工作队列中取出要处理的数
    pManager->LockMutex();
    int nWork = pManager->PopWorkQue();
    pManager->UnlockMutex();
    printf("call Count function.\n");
    pManager->RunThreadFunction(nWork);
  }
  return 0;
}
// 构造方法
CThreadManager::CThreadManager(int (*threadFuction)(int), int nMaxThreadCnt) 
{
  sem_init(&m_sem, 0, 0);
  pthread_mutex_init(&m_mutex, NULL);
  m_threadFuction = threadFuction;
  for(int i=0; i<nMaxThreadCnt; i++)
  {
    CThread* pThread = new CThread(ManageFuction, this);
    printf("thread started.\n");
    m_lstThread.push_back(pThread);
  }
}

</div>

CThread实现的方法

CThreadManager比较简单,封装了创建线程和join线程的函数。

CThread::CThread(void* (*threadFuction)(void*),void* threadArgv) 
{
  // 初始化线程属性
  pthread_attr_t threadAttr;
  pthread_attr_init(&threadAttr);

  pthread_create(&m_thread, &threadAttr, threadFuction, threadArgv);
}

</div>

c++线程池,继承CDoit,实现其中的start和end

/*
 * 多线程管理类
 * 
 */
 
#ifndef CTHREADPOOLMANAGE_H
#define CTHREADPOOLMANAGE_H
#include <iostream>
#include <pthread.h>
#include <unistd.h> 
#include <list>
#include <vector>
#include <time.h>
#include <asm/errno.h>
 
#define USLEEP_TIME 100
#define CHECK_TIME 1
 
 
using namespace std;
class CDoit
{
public:
 virtual int start(void *){};
 virtual int end(){};
};
 
 
class CthreadPoolManage
{
private:
 int _minThreads;  //最少保留几个线程
 int _maxThreads;  //最多可以有几个线程
 int _waitSec;      //空闲多少秒后将线程关闭
 class threadInfo{
  public:
  threadInfo(){
   isbusy = false; 
   doFlag = true;
  }
  //
  pthread_mutex_t mtx=PTHREAD_MUTEX_INITIALIZER;
  pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
  bool isbusy;   //是否空闲
  bool doFlag;
  //
  time_t beginTime;     //线程不工作开始时间
  pthread_t cThreadPid; //线程id
  pthread_attr_t cThreadAttr; //线程属性
  CDoit * doit;         //任务类
  void  * value;        //需要传递的值
 };
 //线程函数
 static void* startThread(void*);
 //任务队列锁
 pthread_mutex_t _duty_mutex;
 //任务队列
 list<threadInfo*> _dutyList;
 //线程队列锁
 pthread_mutex_t _thread_mutex;
 //线程队列
 list<threadInfo*> _threadList;
  
///初始化,创建最小个数线程///
void initThread(); 
///任务分配线程///
static void* taskAllocation(void*arg);
pthread_t tasktPid;
///线程销毁、状态检查线程///
static void* checkThread(void* arg);
pthread_t checktPid;
bool  checkrun;
 
//线程异常退出清理
static void threadCleanUp(void* arg);
 
//
int addThread(list<threadInfo*> *plist,threadInfo* ptinfo);
 
public:
CthreadPoolManage();
/*
保留的最少线程,最多线程数,空闲多久销毁,保留几个线程的冗余
 */
CthreadPoolManage(int min,int max,int waitSec);
~CthreadPoolManage();
 
int start();
//任务注入器
int putDuty(CDoit *,void *);
 
int getNowThreadNum();
 
};
 
#endif // CTHREADPOOLMANAGE_H

</div>

CPP

/*
 * 线程池,线程管理类
 * 
 */
 
#include "cthreadpoolmanage.h"
 
CthreadPoolManage::CthreadPoolManage()
{
 _minThreads = 5;  //最少保留几个线程
 _maxThreads = 5;  //最多可以有几个线程
 _waitSec = 10;      //空闲多少秒后将线程关闭
 pthread_mutex_init(&_duty_mutex, NULL);
 pthread_mutex_init(&_thread_mutex, NULL);
 checkrun = true;
}
 
 
CthreadPoolManage::CthreadPoolManage(int min, int max, int waitSec)
{
  CthreadPoolManage();
  _minThreads = min;  //最少保留几个线程
  _maxThreads = max;  //最多可以有几个线程
  _waitSec = waitSec;      //空闲多少秒后将线程关闭
}
 
CthreadPoolManage::~CthreadPoolManage()
{
 
}
void CthreadPoolManage::threadCleanUp(void* arg)
{
 threadInfo* tinfo = (threadInfo*)arg;
 tinfo->isbusy = false;
 pthread_mutex_unlock(&tinfo->mtx);
 pthread_attr_destroy (&tinfo->cThreadAttr);
 delete tinfo;
}
 
void* CthreadPoolManage::startThread(void* arg)
{
 cout<<"线程开始工作"<<endl;
 threadInfo* tinfo = (threadInfo*)arg;
 pthread_cleanup_push(threadCleanUp,arg);
 while(tinfo->doFlag){
  pthread_mutex_lock(&tinfo->mtx);
  if(tinfo->doit == NULL)
  {
 



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • c++实现简单的线程池
  • c++线程池实现方法
  • c++实现简单的线程池
  • C++线程同步实例分析
  • C++线程池的简单实现方法
  • c++版线程池和任务池示例

相关文章

  • 2017-05-28C++实现简单的HTTP服务器
  • 2017-05-28C语言实现时间戳转日期的算法(推荐)
  • 2017-05-28对比C语言中execv相关的执行文件的三个函数
  • 2017-05-28c++显式类型转换示例详解
  • 2017-05-28C++抽奖程序实现方法
  • 2017-05-28C/C++实现贪吃蛇逐步运动效果
  • 2017-05-28strcpy函数实现简示例命分享
  • 2017-05-28海量数据处理系列之:用C++实现Bitmap算法
  • 2017-05-28c++基础语法:普通继承
  • 2017-05-28C++编程中__if_exists与__if_not_exists语句的用法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • VS2010 C++程序调用C#库
    • c++ vector(向量)使用方法详解(顺序访问vector的多种方式)
    • 有关C++继承与友元、继承与类型转换详解
    • C++中引用的使用总结
    • C/C++中extern "C" 的作用分析
    • c语言读取csv文件和c++读取csv文件示例分享
    • 详解C语言中条件判断语句if和switch的用法
    • 详解C语言中scanf函数使用的一些注意点
    • C语言中获取文件状态的相关函数小结
    • OLEDB打开Excel文件的实现方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有