[转]使用内存信号灯实现C++线程池

sapzj1984 2007-11-09 10:30:10
implement thread pool by semapore

/********************** thread pool interface ******************/

/**
* File : SemThreadPool.h
* Desc :
* Author : daizongh
* Version : V1.0
* Date : 2007-09-21
*/
#ifndef _D_TOOLS_THREAD_POOL_H_070921_
#define _D_TOOLS_THREAD_POOL_H_070921_
#include <pthread.h>
#include <semaphore.h>
#include <vector>
#include "Runnable.h"

#ifndef NULL
#define NULL 0
#endif //NULL

namespace d_tools
{
class ThreadPoolC
{
public:
/**
* constructor. construct a thread pool with DEFAULT_THREAD_COUNT threads
*/
ThreadPoolC();
/**
* constractor. construct a thread pool with size threads
*
* @param size the size of thread pool, must be a positive number, and it
* must be lower to MAX_THREAD_COUNT, it will be reset as
* DEFAULT_THREAD_COUNT if it is not between 1 and MAX_THREAD_COUNT
*/
ThreadPoolC(unsigned int size);
/**
* destructs the thread pool object. this will wait until all thread exit
*
* @see ThreadPoolC::wait()
*/
virtual ~ThreadPoolC();
private:
/**
* close the interface of copy constructor. no implement
*/
ThreadPoolC(const ThreadPoolC &);
/**
* close the interface of assign constructor. no implement
*/
ThreadPoolC & operator=(const ThreadPoolC &);
public:
/**
* add a process handle to the thread pool. this will call runner->run()
* function, the reference or runner must be an implement of RunnableC which
* implements function RunnableC::run()
* waitRunner() will pop the last execute runner, noticeably, this will post a
* semaphore for waitRunner(), otherwise, waitRunner() will wait for the semaphore from
* execute()
*
* @param runner the handler of the thread processing, it must be an implement
* of RunnableC which implements function RunnableC::run()
* @see RunnableC::run()
* @see ThreadPoolC::waitRunner()
*/
void execute(RunnableC * runner);
/**
* close this thread pool. after this call, thread pool will stop after all
* thread handler finished
*/
void shutdown();
/**
* close all handler forcibly. after this call, thread pool will stop immediately
* it will call pthread_cancel() with all threads in the thread pool
* this usually will be called when error occurs
*/
void abort();
/**
* pop the last execute runner. this will block the calling thread if there is no
* semaphore, and it will be notified by execute() calling
* this will called in thread function only, do not call waitRunner() in ur program
*
* @return the runner handler
* @see ThreadPoolC::execute(Runnable *)
*/
RunnableC * waitRunner();
/**
* wait util all threads in the pool finished, this calling will block until shutdown()
* or abort() called
*
* @see ThreadPoolC::shutdown()
* @see ThreadPoolC::abort()
*/
void wait();
private:
void start();
public:
/**
* get the default thread pool size
*
* @return the default thread pool size
*/
static unsigned int getDefaultThreadCount() { return DEFAULT_THREAD_COUNT; }
/**
* set the default thread pool size
*
* @param size the default thread pool size, must be positive number
*/
static void setDefaultThreadCount(unsigned int size) { if( size > 0 ) DEFAULT_THREAD_COUNT = size; }
/**
* get the max thread pool size
*
* @return the max thread pool size
*/
static unsigned int getMaxThreadCount() { return MAX_THREAD_COUNT; }
/**
* set the max thread pool size
*
* @param size max thread pool size, must be positive number
*/
static void setMaxThreadCount(unsigned int size) { MAX_THREAD_COUNT = size; }
protected:
pthread_t * m_thrs_id; //all thread id list
unsigned int m_thr_cnt; //the count of valid threads

sem_t m_sem_consume; //the semaphore for thread notify
pthread_mutex_t m_pr_lock; //lock of thread runner handles
std::vector<RunnableC *> m_pr; //thread runner handlers

static unsigned int DEFAULT_THREAD_COUNT; //default thread size
static unsigned int MAX_THREAD_COUNT; //max thread size
};
}

#endif //_D_TOOLS_THREAD_POOL_H_070921_


...全文
200 1 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
sapzj1984 2007-11-09
  • 打赏
  • 举报
回复
/**************** interface of RunnableC **********************/

/**
* File : Runnable.h
* Desc :
* Author : daizongh
* Version : V1.0
* Date : 2007-09-21
*/
#ifndef _D_TOOLS_RUNNABLE_H_070921_
#define _D_TOOLS_RUNNABLE_H_070921_

namespace d_tools
{
/**
* thread pool runner interface
*
* design a class extended RunnableC and implement the run() interface
* put what u want to do in the implement run()
* then put the object handle of the class as the param
* of d_tools::ThreadPool::excute()
*
* @see d_tools::ThreadPool::execute(d_tools::Runnable *)
*/
class RunnableC
{
public:
RunnableC() { }
virtual ~RunnableC() { }
public:
/**
* put what u want to do in the implement run()
*/
virtual void run() = 0;
};
}

#endif //_D_TOOLS_RUNNABLE_H_070921_


/************************** import implement of ThreadPoolC *********************/

………………
void * fun_for_thread_pool(void * arg)
{
if( arg == NULL )
{
return (void *)1;
}

ThreadPoolC * pool = (ThreadPoolC *)arg;

while( true )
{
RunnableC * runner = pool->waitRunner();
if( runner == NULL )
{
break;
}
runner->run();
}

return (void *)0;
}
………………
void ThreadPoolC::shutdown()
{
for( unsigned int i = 0; i < m_thr_cnt; i++ )
{
sem_post(&m_sem_consume);
}
}

void ThreadPoolC::execute(RunnableC * runner)
{
if( runner == NULL )
{
return;
}

pthread_mutex_lock(&m_pr_lock);
m_pr.push_back(runner);
pthread_mutex_unlock(&m_pr_lock);
sem_post(&m_sem_consume);
}

RunnableC * ThreadPoolC::waitRunner()
{
sem_wait(&m_sem_consume);
pthread_mutex_lock(&m_pr_lock);
RunnableC * pr = m_pr.back();
m_pr.pop_back();
pthread_mutex_unlock(&m_pr_lock);
return pr;
}
………………
void ThreadPoolC::start()
{
………………
for( unsigned int i = 0; i < size; i++ )
{
pthread_t pid;
int ret = pthread_create(&pid, 0, fun_for_thread_pool, (void *)this);
if( ret != -1 )
{
m_thrs_id[m_thr_cnt++] = pid;
}
}
}

567

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧