//ThreadPool.h
#pragma once
#include <cstdio>
#include <unistd.h>
#include <pthread.h>
#include <functional>
#include <queue>
#include <vector>
#include <exception>
#include <iostream>
//封装锁
class MutexLock{
friend class Condition;
public:
MutexLock() { pthread_mutex_init(&mutex, NULL);}
~MutexLock() { pthread_mutex_destroy(&mutex);}
void lock() { pthread_mutex_lock(&mutex);}
void unlock() { pthread_mutex_unlock(&mutex);}
pthread_mutex_t* get() { return &mutex; }
private:
pthread_mutex_t mutex;
};
class MutexLockGuard{
public:
MutexLockGuard(MutexLock& mx) : mutex(mx){ mutex.lock();}
~MutexLockGuard(){mutex.unlock();}
private:
MutexLock& mutex;
};
//封装条件变量
class Condition{
public:
Condition(MutexLock& mx) : mutex(mx){ pthread_cond_init(&cond, NULL);}
~Condition(){pthread_cond_destroy(&cond);}
void wait(){pthread_cond_wait(&cond, mutex.get());}
void notify(){pthread_cond_signal(&cond);}
void notifyAll(){pthread_cond_broadcast(&cond);}
private:
MutexLock& mutex;
pthread_cond_t cond;
};
typedef std::function<void()> Task;
//线程池为单例模式(饿汉)
class ThreadPool{
public:
static ThreadPool* getInstance()
{
return m_threadPool;
}
static void deletePool()
{
if(m_threadPool){
delete m_threadPool;
m_threadPool = NULL;
}
}
public:
static void* run(void* arg); //线程执行函数
void append(Task task); //向队列中插入任务
Task take(); //从队列中取出任务
private:
//构造,析构,拷贝构造,拷贝赋值运算符均为私有
//防止外部调用
ThreadPool(int threadNum, int maxReq);
~ThreadPool();
ThreadPool(const ThreadPool& rhs) = delete;
ThreadPool& operator=(const ThreadPool& rhs) = delete;
private:
int m_threadNum;
int m_maxReq;
MutexLock m_queueLock;
Condition m_notFull; //队列不满信号,此时可以添加
Condition m_notEmpty; //队列非空信号,此时可以取出
std::vector<pthread_t> m_threads;
std::queue<Task> m_tasks;
private:
static ThreadPool* m_threadPool;
};
//ThreadPool.cpp
#include "ThreadPool.h"
#include <pthread.h>
using namespace std;
ThreadPool::ThreadPool(int threadNum, int req)
: m_threadNum(threadNum),
m_maxReq(req),
m_notFull(m_queueLock),
m_notEmpty(m_queueLock)
{
m_threads.resize(m_threadNum, 0);
for(int i = 0; i < m_threadNum; i++){
//创建线程
if(pthread_create(&(m_threads[i]), NULL, run, this) != 0)
{
cout << "create thread error" << endl;
throw std::exception();
}
if(pthread_detach(m_threads[i]) != 0){
cout << "detach error" << endl;
throw std::exception();
}
}
}
ThreadPool::~ThreadPool()
{
}
void* ThreadPool::run(void* arg)
{
ThreadPool* pool = (ThreadPool*)arg;
while(true){
Task task = pool->take();
if(task)
task();
}
return 0;
}
void ThreadPool::append(Task task)
{
MutexLockGuard lock(m_queueLock);
while(m_tasks.size() >= m_maxReq){
m_notFull.wait();
}
m_tasks.push(task);
m_notEmpty.notify();
}
Task ThreadPool::take()
{
MutexLockGuard lock(m_queueLock);
while(m_tasks.empty()){
m_notEmpty.wait();
}
Task task = m_tasks.front();
m_tasks.pop();
m_notFull.notify();
return task;
}
//test.cpp
#include "ThreadPool.h"
#include <sys/time.h>
using namespace std;
void func(int n)
{
cout << "test" << n << endl;
}
ThreadPool* ThreadPool::m_threadPool = new ThreadPool(4, 8);
int main()
{
int i = 0;
ThreadPool* pool = ThreadPool::getInstance();
while(i++ < 10){
pool->append(bind(func, i));
sleep(1);
}
ThreadPool::deletePool();
return 0;
}