#include <pthread.h>
#include <unistd.h>
#include "MutexLock.h"
#include "Condition.h"
#include <vector>
#include <future>
#include <list>
#include <assert.h>
#include <iostream>
using namespace std;
// T : 任务类型
template <typename T>
class threadpool : uncoypable {
private:
int max_thread;
int max_job;
vector <pthread_t> pthread_poll;
list<T*> m_myworkqueue;
MutexLock m_mutex;
Condition m_cond;
bool m_stop;
public:
threadpool();
~threadpool();
bool addjob(T* request);
private:
static void* worker(void* arg);
static void* test(void* arg);
void run();
};
template <typename T>
threadpool<T> :: threadpool() : m_cond(m_mutex){
max_thread = 8;
pthread_poll.reserve(8);
max_job = 1000;
m_stop = false;
int ret = 0;
for (int i = 0;i < max_thread;++ i) {
cout << "create the pthread :" << i << endl;
ret = pthread_create(&pthread_poll[i],NULL,worker,(void*)this);
assert( 0 == ret);
ret = pthread_detach(pthread_poll[i]);
assert(0 == ret);
}
}
template <typename T>
bool threadpool<T> :: addjob(T* request) {
MutexLockGuard lock(m_mutex);
if (m_myworkqueue.size() > max_job) {
return false;
}
m_myworkqueue.push_back(request);
m_cond.notify();
}
template <typename T>
void* threadpool<T> :: worker(void* arg) {
threadpool* pool = (threadpool*)arg;
pool -> run();
return pool;
}
template<typename T>
threadpool<T> :: ~threadpool() {
m_stop = true;
}
template<typename T>
void threadpool<T> :: run() {
while (!m_stop) {
// 这里不用MutexLockGuard是想让request -> doit()不在临界区内
m_mutex.lock();
while (m_myworkqueue.empty()) {
m_cond.wait();
}
if (m_stop) break;
T* request = m_myworkqueue.front();
m_myworkqueue.pop_front();
m_mutex.unlock();
request -> doit();
}
}
uncopyable类
# pragma once
class uncoypable {
protected:
uncoypable() {}
~uncoypable() {}
private:
uncoypable(const uncoypable&);
uncoypable& operator = (const uncoypable&);
};
MutexLock类
# pragma once
#include <pthread.h>
#include "uncopyable.h"
class MutexLock : uncoypable {
public:
MutexLock() {pthread_mutex_init(&mutex,nullptr);}
~MutexLock() {
pthread_mutex_lock(&mutex);
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;
private:
friend class Condition;
};
class MutexLockGuard : uncoypable {
public:
explicit MutexLockGuard(MutexLock& _mutex) : mutex(_mutex) {mutex.lock();}
~MutexLockGuard() {mutex.unlock();}
private:
MutexLock& mutex;
};
Condition类
# pragma once
#include <errno.h>
# include <pthread.h>
#include <time.h>
#include <cstdint>
#include "MutexLock.h"
#include "uncopyable.h"
class Condition : uncoypable {
public:
explicit Condition(MutexLock& _mutex) : mutex (_mutex) {
pthread_cond_init(&cond,nullptr);
}
~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);}
bool waitForSeconds(int seconds) {
struct timespec abstime;
clock_gettime(CLOCK_REALTIME,&abstime);
abstime.tv_sec += static_cast<time_t>(seconds);
return ETIMEDOUT == pthread_cond_timedwait(&cond,mutex.get(),&abstime);
}
private:
MutexLock& mutex;
pthread_cond_t cond;
};
测试
#include "ThreadPool.h"
#include <pthread.h>
#include <vector>
#include <unistd.h>
#include <iostream>
using namespace std;
typedef struct {
void doit() {
cout << "abc" << endl;
}
}task;
int main () {
clock_t start,end;
double totaltime;
start = clock();
threadpool<task>* pool = new threadpool<task>();
task* testfunc = new task();
for (int i = 0;i < 1000;++ i) {
// pool -> addjob(testfunc); // 使用线程
testfunc->doit(); // 不使用线程
}
end = clock();
totaltime = (double)(end - start) / CLOCKS_PER_SEC;
sleep(1);
cout << "use " << totaltime << endl;
return 0;
}
结果发现用了线程池后所用时间为 0.000399,而不用线程所用时间为0.001581