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_info*> TASK_LIST;
typedef list<task_info*>::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<thread_pool*> (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 < n; i++)
  {
    int ret = pthread_create(&m_pids[i], NULL, thread_func, (void*) this);
    if (ret != 0)
      break;
    m_thread_cnt++;
  }
  return m_thread_cnt;
}
void thread_pool::delete_threads()
{
  for (int i = 0; i < m_thread_cnt; i++)
  {
    void* retval;
    pthread_cancel(m_pids[i]);
    pthread_join(m_pids[i], &retval);
  }
  m_thread_cnt = 0;
}
void thread_pool::set_tasklist(task_list* plist)
{
  m_tasklist = plist;
}
void thread_pool::del_tasklist()
{
  m_tasklist = NULL;
}

文件名: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++程序设计有所帮助。

(0)

相关推荐

  • C++线程池的简单实现方法

    本文以实例形式较为详细的讲述了C++线程池的简单实现方法.分享给大家供大家参考之用.具体方法如下: 一.几个基本的线程函数: 1.线程操纵函数: int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, (void*)(*start_rtn)(void *), void *arg); //创建 void pthread_exit(void *retval); //终止自身 int pthread_cancel(pthread_

  • c++实现简单的线程池

    这是对pthread线程的一个简单应用 1.      实现了线程池的概念,线程可以重复使用. 2.      对信号量,互斥锁等进行封装,业务处理函数中只需写和业务相关的代码. 3.      移植性好.如果想把这个线程池代码应用到自己的实现中去,只要写自己的业务处理函数和改写工作队列数据的处理方法就可以了. Sample代码主要包括一个主程序和两个线程实现类 ThreadTest.cpp:主程序 CThreadManager:线程管理Class,线程池的实现类 CThread:线程Class

  • C语言实现支持动态拓展和销毁的线程池

    本文实例介绍了C 语言实现线程池,支持动态拓展和销毁,分享给大家供大家参考,具体内容如下 实现功能 1.初始化指定个数的线程 2.使用链表来管理任务队列 3.支持拓展动态线程 4.如果闲置线程过多,动态销毁部分线程 #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <signal.h> /*线程的任务队列由,函数和参数组成,任务由链表来进行管理*/ typedef str

  • 利用ace的ACE_Task等类实现线程池的方法详解

    本代码应该是ace自带的例子了,但是我觉得是非常好的,于是给大家分享一下.注释非常详细啊.头文件 复制代码 代码如下: #ifndef THREAD_POOL_H#define THREAD_POOL_H/* In order to implement a thread pool, we have to have an object that   can create a thread.  The ACE_Task<> is the basis for doing just   such a

  • 深入解析C++编程中线程池的使用

    为什么需要线程池 目前的大多数网络服务器,包括Web服务器.Email服务器以及数据库服务器等都具有一个共同点,就是单位时间内必须处理数目巨大的连接请求,但处理时间却相对较短. 传 统多线程方案中我们采用的服务器模型则是一旦接受到请求之后,即创建一个新的线程,由该线程执行任务.任务执行完毕后,线程退出,这就是是"即时创建,即 时销毁"的策略.尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务是执行时间较短,而且执行次数极其频繁,那么服务器将处于 不停的创建线程,

  • c++版线程池和任务池示例

    commondef.h 复制代码 代码如下: //单位秒,监测空闲列表时间间隔,在空闲队列中超过TASK_DESTROY_INTERVAL时间的任务将被自动销毁const int CHECK_IDLE_TASK_INTERVAL = 300;//单位秒,任务自动销毁时间间隔const int TASK_DESTROY_INTERVAL = 60; //监控线程池是否为空时间间隔,微秒const int IDLE_CHECK_POLL_EMPTY = 500; //线程池线程空闲自动退出时间间隔

  • python实现线程池的方法

    本文实例讲述了python实现线程池的方法.分享给大家供大家参考.具体如下: 原理:建立一个任务队列,然多个线程都从这个任务队列中取出任务然后执行,当然任务队列要加锁,详细请看代码 文件名:thrd_pool.py 系统环境:ubuntu linux & python2.6 import threading import time import signal import os class task_info(object): def __init__(self): self.func = No

  • c++线程池实现方法

    本文实例讲述了c++线程池实现方法.分享给大家供大家参考.具体分析如下: 下面这个线程池是我在工作中用到过的,原理还是建立一个任务队列,让多个线程互斥的在队列中取出任务,然后执行,显然,队列是要加锁的 环境:ubuntu linux 文件名:locker.h #ifndef LOCKER_H_ #define LOCKER_H_ #include "pthread.h" class locker { public: locker(); virtual ~locker(); bool l

  • Python自定义线程池实现方法分析

    本文实例讲述了Python自定义线程池实现方法.分享给大家供大家参考,具体如下: 关于python的多线程,由与GIL的存在被广大群主所诟病,说python的多线程不是真正的多线程.但多线程处理IO密集的任务效率还是可以杠杠的. 我实现的这个线程池其实是根据银角的思路来实现的. 主要思路: 任务获取和执行: 1.任务加入队列,等待线程来获取并执行. 2.按需生成线程,每个线程循环取任务. 线程销毁: 1.获取任务是终止符时,线程停止. 2.线程池close()时,向任务队列加入和已生成线程等量的

  • 一种类似JAVA线程池的C++线程池实现方法

    什么是线程池 线程池(thread pool)是一种线程使用模式.线程过多或者频繁创建和销毁线程会带来调度开销,进而影响缓存局部性和整体性能.而线程池维护着多个线程,等待着管理器分配可并发执行的任务.这避免了在处理短时间任务时创建与销毁线程的代价,以及保证了线程的可复用性.线程池不仅能够保证内核的充分利用,还能防止过分调度. 线程池的实现 线程池在JAVA平台上已经有成熟的实现方式,本文介绍参考JAVA线程池实现方式实现的C++线程池类库. 该类库代码已上传至github仓库中,下载地址为:ht

  • C++11 简单实现线程池的方法

    什么是线程池 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中.如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙.如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值.超过最大值的线程可以排队,但他们要等到其他线程完成后才启动. 不使用

  • 火遍全网的Hutool使用Builder模式创建线程池的方法

    前言 Builder 设计模式也叫做 构建者模式或者建造者模式,名字只是一种叫法,当聊起三种名称的时候知道是怎么回事就行 Builder 设计模式在作者编码过程中,属于比较常用的模式之一.优秀的设计模式总是会受到广大开发者的青睐,Hutool 也是其中之一 因为上周编写的业务需要用到线程池,就去 Hutool thread 包下看了看,还真有惊喜,学习到了一种之前编码中没用过的 Builder 模式实现 这里必须提一句:设计模式重要的是思想,一种设计模式可能不止一种实现方式 Builder 模式

  • Java线程池execute()方法源码全面解析

    先看作者给出的注释来理解线程池到底有什么作用 * Thread pools address two different problems: they usually * provide improved performance when executing large numbers of * asynchronous tasks, due to reduced per-task invocation overhead, * and they provide a means of boundin

  • 模拟简单Java线程池的方法详解

    目录 一. 前言 二.线程池是什么? 三.线程池构造方法ThreadPoolExecutor的构造方法的参数都是啥意思? 四.模拟实现一个线程池 总结 一. 前言 为了实现并发编程,于是就引入了进程这个概念.进程就相当于操作系统的一个任务.多个进程同时执行任务,就实现了并发编程,能够更快的执行. 但是由于进程还不够轻量,创建一个进程,销毁一个进程消耗的资源不可忽视.如果进程数量不多的情况下,这些资源消耗是可以接受的,但是如果频繁的创建.销毁进程.就是一笔很大的开销了. 那要怎么办呢? 为了解决这

  • java 注解实现一个可配置线程池的方法示例

    前言 项目需要多线程执行一些Task,为了方便各个服务的使用.特意封装了一个公共工具类,下面直接撸代码: PoolConfig(线程池核心配置参数): /** * <h1>线程池核心配置(<b style="color:#CD0000">基本线程池数量.最大线程池数量.队列初始容量.线程连接保持活动秒数(默认60s)</b>)</h1> * * <blockquote><code> * <table bord

  • C/C++ 原生API实现线程池的方法

    线程池有两个核心的概念,一个是任务队列,一个是工作线程队列.任务队列负责存放主线程需要处理的任务,工作线程队列其实是一个死循环,负责从任务队列中取出和运行任务,可以看成是一个生产者和多个消费l者的模型.在一些高并发的网络应用中,线程池也是常用的技术.陈硕大神推荐的C++多线程服务端编程模式为:one loop per thread + thread pool,通常会有单独的线程负责接受来自客户端的请求,对请求稍作解析后将数据处理的任务提交到专门的计算线程池. ThreadPool 线程池同步事件

随机推荐