文章目录
- 1、C++11线程池代码
-
- threadpool.h
- threadpool.cpp
- main.cpp
- 编译
- 2、Linux C++线程池
-
- pthreadPool.h
- pthreadPool.cpp
- pthreadPool.cpp
- 编译
1、C++11线程池代码
threadpool.h
#ifndef _THREADPOOL_H
#define _THREADPOOL_H
#include
#include
#include
#include
#include
#include
#ifdef WIN32
#include
#else
#include
#endif
using namespace std;
void getNow(timeval *tv);
int64_t getNowMs();
#define TNOW getNow()
#define TNOWMS getNowMs()
class ThreadPool
{
protected:
struct TaskFunc
{
TaskFunc(uint64_t expireTime) : _expireTime(expireTime)
{ }
std::function<void()> _func;
int64_t _expireTime = 0;
};
typedef shared_ptr<TaskFunc> TaskFuncPtr;
public:
ThreadPool();
virtual ~ThreadPool();
bool init(size_t num);
size_t getThreadNum(){
std::unique_lock<std::mutex> lock(_mutex);
return _threads.size();
}
size_t getJobNum(){
std::unique_lock<std::mutex> lock(_mutex);
return _tasks.size();
}
void stop();
bool start();
template <class F, class... Args>
auto exec(F&& f, Args&&... args) -> std::future<decltype(f(args...))>
{
return exec(0,f,args...);
}
template <class F, class... Args>
auto exec(int64_t timeoutMs, F&& f, Args&&... args) ->
std::future<decltype(f(args...))>
{
int64_t expireTime = (timeoutMs == 0 ? 0 : TNOWMS + timeoutMs);
using RetType = decltype(f(args...));
auto task = std::make_shared<std::packaged_task<RetType()>>
(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
TaskFuncPtr fPtr = std::make_shared<TaskFunc>(expireTime);
fPtr->_func = [task]() {
(*task)();
};
std::unique_lock<std::mutex> lock(_mutex);
_tasks.push(fPtr);
_condition.notify_one();
return task->get_future();;
}
bool waitForAllDone(int millsecond = -1);
protected:
bool get(TaskFuncPtr&task);
bool isTerminate() { return _bTerminate; }
void run();
protected:
queue<TaskFuncPtr> _tasks;
std::vector<std::thread*> _threads;
std::mutex _mutex;
std::condition_variable _condition;
size_t _threadNum;
bool _bTerminate;
std::atomic<int> _atomic{ 0 };
};
#endif
threadpool.cpp
#include "threadpool.h"
ThreadPool::ThreadPool()
: _threadNum(1), _bTerminate(false){
}
ThreadPool::~ThreadPool(){
stop();
}
bool ThreadPool::init(size_t num)
{
std::unique_lock<std::mutex> lock(_mutex);
if (!_threads.empty()){
return false;
}
_threadNum = num;
return true;
}
void ThreadPool::stop()
{
{
std::unique_lock<std::mutex> lock(_mutex);
_bTerminate = true;
_condition.notify_all();
}
for (size_t i = 0; i < _threads.size(); i++)
{
if(_threads[i]->joinable()){
_threads[i]->join();
}
delete _threads[i];
_threads[i] = NULL;
}
std::unique_lock<std::mutex> lock(_mutex);
_threads.clear();
}
bool ThreadPool::start()
{
std::unique_lock<std::mutex> lock(_mutex);
if (!_threads.empty()){
return false;
}
for (size_t i = 0; i < _threadNum; i++){
_threads.push_back(new thread(&ThreadPool::run, this));
}
return true;
}
bool ThreadPool::get(TaskFuncPtr& task)
{
std::unique_lock<std::mutex> lock(_mutex);
if (_tasks.empty())
{
_condition.wait(lock, [this] { return _bTerminate || !_tasks.empty();});
}
if (_bTerminate)
return false;
if (!_tasks.empty())
{
task = std::move(_tasks.front());
_tasks.pop();
return true;
}
return false;
}
void ThreadPool::run()
{
while (!isTerminate())
{
TaskFuncPtr task;
bool ok = get(task);
if (ok)
{
++_atomic;
try
{
if (task->_expireTime != 0 && task->_expireTime < TNOWMS ){
}
else{
task->_func();
}
}
catch (...){
}
--_atomic;
std::unique_lock<std::mutex> lock(_mutex);
if (_atomic == 0 && _tasks.empty()){
_condition.notify_all();
}
}
}
}
bool ThreadPool::waitForAllDone(int millsecond)
{
std::unique_lock<std::mutex> lock(_mutex);
if (_tasks.empty())
return true;
if (millsecond < 0){
_condition.wait(lock, [this] { return _tasks.empty(); });
return true;
}
else{
return _condition.wait_for(lock, std::chrono::milliseconds(millsecond),
[this] { return _tasks.empty(); });
}
}
int gettimeofday(struct timeval &tv)
{
#if WIN32
time_t clock;
struct tm tm;
SYSTEMTIME wtm;
GetLocalTime(&wtm);
tm.tm_year = wtm.wYear - 1900;
tm.tm_mon = wtm.wMonth - 1;
tm.tm_mday = wtm.wDay;
tm.tm_hour = wtm.wHour;
tm.tm_min = wtm.wMinute;
tm.tm_sec = wtm.wSecond;
tm. tm_isdst = -1;
clock = mktime(&tm);
tv.tv_sec = clock;
tv.tv_usec = wtm.wMilliseconds * 1000;
return 0;
#else
return ::gettimeofday(&tv, 0);
#endif
}
void getNow(timeval *tv)
{
#if TARGET_PLATFORM_IOS || TARGET_PLATFORM_LINUX
int idx = _buf_idx;
*tv = _t[idx];
if(fabs(_cpu_cycle - 0) < 0.0001 && _use_tsc){
addTimeOffset(*tv, idx);
}
else{
TC_Common::gettimeofday(*tv);
}
#else
gettimeofday(*tv);
#endif
}
int64_t getNowMs()
{
struct timeval tv;
getNow(&tv);
return tv.tv_sec * (int64_t)1000 + tv.tv_usec / 1000;
}
main.cpp
#include
#include "threadpool.h"
using namespace std;
void func0(){
cout << "func0()" << endl;
}
void func1(int a){
cout << "func1() a=" << a << endl;
}
void func2(int a, string b){
cout << "func1() a=" << a << ", b=" << b<< endl;
}
void test1()
{
ThreadPool threadpool;
threadpool.init(2);
threadpool.start();
threadpool.exec(1000,func0);
threadpool.exec(func1, 10);
threadpool.exec(func2, 20, "darren");
threadpool.waitForAllDone();
threadpool.stop();
}
int func1_future(int a)
{
cout << "func1() a=" << a << endl;
return a;
}
string func2_future(int a, string b)
{
cout << "func1() a=" << a << ", b=" << b<< endl;
return b;
}
void test2()
{
ThreadPool threadpool;
threadpool.init(10);
threadpool.start();
std::future<decltype (func1_future(0))> result1 =
threadpool.exec(func1_future, 10);
std::future<string> result2 = threadpool.exec(func2_future, 20, "darren");
std::cout << "result1: " << result1.get() << std::endl;
std::cout << "result2: " << result2.get() << std::endl;
threadpool.waitForAllDone();
threadpool.stop();
}
int main()
{
test2();
cout << "Hello World!" << endl;
return 0;
}
编译
all:main
main:main.cpp
g++ -o main main.cpp threadpool.cpp -std=c++11 -pthread
clean:
rm -rf main
2、Linux C++线程池
pthreadPool.h
#ifndef __PTHREADPOOL_H_
#define __PTHREADPOOL_H_
#include
#include
#include
#include
#include
#include
using namespace std;
struct student
{
char name[256];
unsigned int age;
int id;
};
class pthreadPool
{
public:
pthreadPool();
~pthreadPool();
public:
bool createPthread(int threadNUm = 5);
void stopAll();
void call();
void inMsgRecvQueueAndSignal(char* buf);
private:
static void* threadFunc(void* threadData);
void clearMsgRecvQueue();
void msgDispose(char* jobbuf);
private:
struct pthreadItem
{
bool isruning;
pthreadPool* _pThis;
pthread_t _Handle;
pthreadItem(pthreadPool* pthis):_pThis(pthis),isruning(false){}
~pthreadItem(){}
};
private:
static pthread_cond_t m_pthreadCond;
static pthread_mutex_t m_pthreadMutex;
static bool m_shutdown;
int m_iThreadNum;
time_t m_iLastTime;
atomic<int> m_iRunThreadNum;
vector<pthreadItem*> m_vThread;
list<char*> m_msgRecvQueue;
int m_iRecvQueueCount;
};
#endif
pthreadPool.cpp
#include "pthreadPool.h"
pthread_cond_t pthreadPool::m_pthreadCond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t pthreadPool::m_pthreadMutex = PTHREAD_MUTEX_INITIALIZER;
bool pthreadPool::m_shutdown = false;
pthreadPool::pthreadPool()
{
m_iRunThreadNum = 0;
m_iLastTime = 0;
m_iRecvQueueCount = 0;
}
pthreadPool::~pthreadPool()
{
clearMsgRecvQueue();
}
bool pthreadPool::createPthread(int threadNum)
{
if(!threadNum) return false;
m_iThreadNum = threadNum;
pthreadItem* item;
int errCode = 0;
for(int i=0;i<threadNum;i++){
item = new pthreadItem(this);
errCode = pthread_create(&(item->_Handle),NULL,pthreadPool::threadFunc,item);
if(errCode!=0){
cout<<"线程创建失败:"<<i<<endl;
return false;
}
m_vThread.push_back(item);
}
vector<pthreadItem*>::iterator iter;
lblfor:
for(iter = m_vThread.begin();iter!=m_vThread.end();iter++){
if((*iter)->isruning == false){
usleep(100*1000);
goto lblfor;
}
}
return true;
}
void* pthreadPool::threadFunc(void* threadData)
{
pthreadItem* pThread = (pthreadItem*)threadData;
pthreadPool* pPoll = pThread->_pThis;
int errCode = 0;
pthread_t tid = pthread_self();
while(true){
errCode = pthread_mutex_lock(&m_pthreadMutex);
if(errCode!=0){
cout<<"pthread_mutex_lock fail threadFunc errCode"<<errCode<<endl;
return (void*)0;
}
while((pPoll->m_msgRecvQueue.size() == 0) && m_shutdown == false){
if(pThread->isruning == false)
pThread->isruning = true;
pthread_cond_wait(&m_pthreadCond,&m_pthreadMutex);
}
if(m_shutdown){
pthread_mutex_unlock(&m_pthreadMutex);
break;
}
char* jobbuf = pPoll->m_msgRecvQueue.front();
pPoll->m_msgRecvQueue.pop_front();
--pPoll->m_iRecvQueueCount;
pthread_mutex_unlock(&m_pthreadMutex);
++pPoll->m_iRunThreadNum;
pthreadPool.cpp
#include "pthreadPool.h"
int main()
{
pthreadPool* pool = new pthreadPool();
pool->createPthread(6);
for(int i=0;i<1000;i++){
struct student* stu = new student();
sprintf(stu->name,"name-%d",i);
stu->age = i;
stu->id = 1000+i;
pool->inMsgRecvQueueAndSignal((char*)stu);
}
pool->stopAll();
if(pool!=NULL){
delete pool;
pool = NULL;
}
pthread_exit(0);
}
编译
all:pthreadPool
pthreadPool:pthreadPool.h pthreadPool.cpp pthreadPoolText.cpp
g++ -o pthreadPool pthreadPool.cpp pthreadPoolText.cpp -pthread -std=c++11