热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

c++线程池实现方法

这篇文章主要介绍了c++线程池实现方法,实例分析了C++线程池的原理与相关实现技巧,需要的朋友可以参考下

本文实例讲述了c++线程池实现方法。分享给大家供大家参考。具体分析如下:

下面这个线程池是我在工作中用到过的,原理还是建立一个任务队列,让多个线程互斥的在队列中取出任务,然后执行,显然,队列是要加锁的

环境:ubuntu linux

文件名:locker.h

#ifndef LOCKER_H_ 
#define LOCKER_H_ 
#include "pthread.h" 
class locker 
{ 
public: 
  locker(); 
  virtual ~locker(); 
  bool lock(); 
  void unlock(); 
private: 
  pthread_mutex_t   m_mutex; 
}; 
#endif /* LOCKER_H_ */ 

文件名:locker.cpp

#include "locker.h" 
locker::locker() 
{ 
  pthread_mutex_init(&m_mutex, 0); 
} 
locker::~locker() 
{ 
  pthread_mutex_destroy(&m_mutex); 
} 
bool locker::lock() 
{ 
  if(0 == pthread_mutex_lock(&m_mutex)) 
    return true; 
  return false; 
} 
void locker::unlock() 
{ 
  pthread_mutex_unlock(&m_mutex); 
}

文件名:task_list.h

#ifndef TASK_LIST_H_ 
#define TASK_LIST_H_ 
#include "list" 
#include "locker.h" 
#include "netinet/in.h" 
#include "semaphore.h" 
using namespace std; 
typedef void* (*THREAD_FUNC)(void*); 
// 线程池中运行的任务,对于下行任务,sin中包含目的地址信息 
// parm0指向发出数据的对象,parm1指向数据,parm2为数据的长度 
typedef struct 
{ 
  THREAD_FUNC func; 
  void* parm0; 
  void* parm1; 
  void* parm2; 
} task_info; 
typedef list TASK_LIST; 
typedef list::iterator PTASK_LIST; 
class task_list 
{ 
public: 
  task_list(); 
  virtual ~task_list(); 
  void append_task(task_info* tsk); 
  task_info* fetch_task(); 
private: 
  TASK_LIST m_tasklist; 
  locker m_lk; 
  sem_t m_sem; 
}; 
#endif /* TASK_LIST_H_ */

文件名:task_list.cpp

#include "task_list.h" 
task_list::task_list() 
{ 
  // Init Semaphore 
  sem_init(&m_sem, 0, 0); 
  m_tasklist.clear(); 
} 
task_list::~task_list() 
{ 
  while(!m_tasklist.empty()) 
  { 
    task_info* tr = m_tasklist.front(); 
    m_tasklist.pop_front(); 
    if(tr) 
      delete tr; 
  } 
  // Destroy Semaphore 
  sem_destroy(&m_sem); 
} 
void task_list::append_task(task_info* tsk) 
{ 
  // Lock before Modify the list 
  m_lk.lock(); 
  m_tasklist.push_back(tsk); 
  m_lk.unlock(); 
  // Increase the Semaphore 
  sem_post(&m_sem); 
} 
task_info* task_list::fetch_task() 
{ 
  task_info* tr = NULL; 
  sem_wait(&m_sem); 
  m_lk.lock(); 
  tr = m_tasklist.front(); 
  m_tasklist.pop_front(); 
  m_lk.unlock(); 
  return tr; 
}

文件名:thread_pool.h

#ifndef THREAD_POOL_H_ 
#define THREAD_POOL_H_ 
#include "task_list.h" 
#include "pthread.h" 
#define DEFAULT_THREAD_COUNT  4 
#define MAXIMUM_THREAD_COUNT  1000 
class thread_pool 
{ 
public: 
  thread_pool(); 
  virtual ~thread_pool(); 
  int create_threads(int n = DEFAULT_THREAD_COUNT); 
  void delete_threads(); 
  void set_tasklist(task_list* plist); 
  void del_tasklist(); 
protected: 
  static void* thread_func(void* parm); 
  task_info* get_task(); 
private: 
  int       m_thread_cnt; 
  pthread_t    m_pids[MAXIMUM_THREAD_COUNT]; 
  task_list*   m_tasklist; 
}; 
#endif /* THREAD_POOL_H_ */ 

文件名:thread_pool.cpp

#include "thread_pool.h" 
thread_pool::thread_pool() 
{ 
  m_thread_cnt = 0; 
  m_tasklist = NULL; 
} 
thread_pool::~thread_pool() 
{ 
  delete_threads(); 
} 
task_info* thread_pool::get_task() 
{ 
  task_info* tr; 
  if (m_tasklist) 
  { 
    tr = m_tasklist->fetch_task(); 
    return tr; 
  } 
  return NULL; 
} 
void* thread_pool::thread_func(void* parm) 
{ 
  thread_pool *ptp = static_cast (parm); 
  task_info *task; 
  while (true) 
  { 
    task = ptp->get_task(); 
    if (task) 
    { 
      (*task->func)(task); 
      //delete task; //func负责释放task_info 
    } 
  } 
  return NULL; 
} 
int thread_pool::create_threads(int n) 
{ 
  if (n > MAXIMUM_THREAD_COUNT) 
    n = MAXIMUM_THREAD_COUNT; 
  delete_threads(); 
  for (int i = 0; i 

文件名:test.cpp

#include "unistd.h" 
#include "stdio.h" 
#include "stdlib.h" 
#include "task_list.h" 
#include "thread_pool.h" 
void* fun(void *parm) 
{ 
  task_info* ptk = (task_info*)parm; 
  pid_t tid = pthread_self(); 
  int count = (int)ptk->parm0; 
  printf("count=%d, tid=%d\n", count, tid); 
  return NULL; 
} 
int main() 
{ 
  int count = 0; 
  thread_pool tp; 
  task_list tl; 
  tp.create_threads(4 - 1); 
  tp.set_tasklist(&tl); 
  while (1) 
  { 
    task_info* pti = NULL; 
    pti = (task_info *) malloc(sizeof(task_info)); 
    pti->func = fun; 
    pti->parm0 = (void *)count; 
    tl.append_task(pti); 
    count++; 
    sleep(2); 
  } 
// printf("hello,world\n"); 
  return 0; 
} 

编译运行,我是用ecplise建立的automake工程,所以只要修改一下Makefile.am就可以编译成功了
文件名:Makefile.am

bin_PROGRAMS=test 
test_SOURCES=test.cpp locker.h locker.cpp \ 
              task_list.h task_list.cpp \ 
              thread_pool.h thread_pool.cpp 
test_LDADD=-lpthread 

执行结果:

count=0, tid=-1219888272 
count=1, tid=-1219888272 
count=2, tid=-1228280976 
count=3, tid=-1236673680 
count=4, tid=-1219888272 
count=5, tid=-1228280976 
count=6, tid=-1236673680 
count=7, tid=-1219888272 
count=8, tid=-1228280976 
count=9, tid=-1236673680 

希望本文所述对大家的C++程序设计有所帮助。


推荐阅读
  • Linuxchmod目录权限命令图文详解在Linux文件系统模型中,每个文件都有一组9个权限位用来控制谁能够读写和执行该文件的内容。对于目录来说,执行位的作用是控制能否进入或者通过 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • Ubuntu 9.04中安装谷歌Chromium浏览器及使用体验[图文]
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 近年来,大数据成为互联网世界的新宠儿,被列入阿里巴巴、谷歌等公司的战略规划中,也在政府报告中频繁提及。据《大数据人才报告》显示,目前全国大数据人才仅46万,未来3-5年将出现高达150万的人才缺口。根据领英报告,数据剖析人才供应指数最低,且跳槽速度最快。中国商业结合会数据剖析专业委员会统计显示,未来中国基础性数据剖析人才缺口将高达1400万。目前BAT企业中,60%以上的招聘职位都是针对大数据人才的。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文主要讨论了在xps15上安装双系统win10和MacOS后,win10无法正常更新的问题。分析了可能的引导问题,并提供了解决方法。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
author-avatar
小果康康维五_469
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有