threadpool主要有4個函數:
1.init() 初始化線程池,線程數量自己定
2.destroy() 銷燬線程池,所有線程會被立即銷燬
3.add_event() 增加事件到線程池中,以及喚醒線程對事件作處理
4.thread_process() 這個函數是static的,就是用來做線程的回調函數,線程們就是在這裏等待喚醒處理事件
threadpool.h
/*
* Name: threadpool
* Date: 8-12-2015
* Author: Sumkee
* Brief: A thread pool which created more than one threads
* to process some events
*
*/
#ifndef THREADPOOL_H__
#define THREADPOOL_H_
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <pthread.h>
#include <deque>
using namespace std;
class threadpool {
public:
// Event
typedef struct _event {
void (*callback)(void*); // Callback function
void *args; // Arguments
} event;
threadpool();
~threadpool();
/*
* Name: init
* Brief: Initialize the thread pool
* @thread_count: Number of thread, the default value is 4
* return: Success return true , else return false
*/
bool init(const int thread_count=4);
/*
* Name: destroy
* Brief: Destroy and free the thread pool after all events done
*
*/
void destroy();
/*
* Name: add_event
* Brief: Add event to event buffer
* @ent: The event that include callback function and argument
* return: Success return true, else return false
*
*/
bool add_event(const threadpool::event ent);
private:
bool m_is_init; // Determine that if the thread pool initialized
pthread_mutex_t m_mutex; // The mutex for thread-safe
pthread_cond_t m_cond; // The cond value
deque<pthread_t> m_thrs; // The threads id
deque<event> m_events; // The events
bool m_is_closing; // When thread pool is closing
/*
* Name: put_error
* Brief: Output error string
* @err: Error string
*
*/
void put_error(const string err);
/*
* Name: thread_procee
* Brief: Threads wait here for event
* @m_this: Point to thread pool because this is static function
*
*/
static void* thread_process(void *m_this);
};
#endif
threadpool.cpp
<pre name="code" class="cpp">#include "threadpool.h"
ThreadPool::ThreadPool() {
// Initialize some variables
m_is_init = false;
m_is_closing = false;
// Initialize mutex
pthread_mutex_init(&m_mutex, 0);
// Initialize the cond
pthread_cond_init(&m_cond, 0);
}
ThreadPool::~ThreadPool() {
// Free variables
pthread_mutex_destroy(&m_mutex);
pthread_cond_destroy(&m_cond);
}
bool ThreadPool::init(const int thread_count) {
pthread_mutex_lock(&m_mutex);
if(m_is_init) {
put_error("Thread pool already initialized");
pthread_mutex_unlock(&m_mutex);
return false;
}
// Create threads
for(int i=0; i<thread_count; ++i) {
pthread_t pthr = 0;
pthread_create(&pthr, 0, ThreadPool::thread_process, this);
m_thrs.push_back(pthr);
}
m_is_init = true;
pthread_mutex_unlock(&m_mutex);
return true;
}
void ThreadPool::destroy() {
pthread_mutex_lock(&m_mutex);
m_is_closing = true;
pthread_cond_broadcast(&m_cond);
pthread_mutex_unlock(&m_mutex);
// Wait for threads destroied
for(deque<pthread_t>::const_iterator iter=m_thrs.begin();
iter!=m_thrs.end(); ++iter) {
pthread_join(*iter, 0);
}
}
bool ThreadPool::add_event(CALLBACK_FN callback, void *args) {
pthread_mutex_lock(&m_mutex);
if(!callback) {
put_error("Callback function can't be null");
return false;
}
if(!m_is_init) {
put_error("Thread pool dosen't initialized");
pthread_mutex_unlock(&m_mutex);
return false;
} else if(m_is_closing) {
put_error("Thread pool is closing");
pthread_mutex_unlock(&m_mutex);
return false;
}
Event ent;
ent.callback = callback;
ent.args = args;
// Push event
m_events.push_back(ent);
// Notice threads
if(m_events.size() == 1) {
pthread_cond_signal(&m_cond);
} else {
pthread_cond_broadcast(&m_cond);
}
pthread_mutex_unlock(&m_mutex);
return true;
}
void ThreadPool::put_error(const string err) {
cout << "ThreadPool:" << err << endl;
}
void* ThreadPool::thread_process(void *m_this) {
ThreadPool *ptp = static_cast<ThreadPool*>(m_this);
while(1) {
pthread_mutex_lock(&ptp->m_mutex);
// Wait for notice
while(ptp->m_events.size()==0 && !ptp->m_is_closing) {
pthread_cond_wait(&ptp->m_cond, &ptp->m_mutex);
}
if(ptp->m_is_closing && ptp->m_events.size()==0) {
pthread_mutex_unlock(&ptp->m_mutex);
}
// Get event
ThreadPool::Event ent = ptp->m_events[0];
ptp->m_events.pop_front();
pthread_mutex_unlock(&ptp->m_mutex);
// Process event
ent.callback(ent.args);
}
pthread_mutex_unlock(&ptp->m_mutex);
return 0;
}
void test_proc(void *args) {
usleep(100*1000);
cout << pthread_self() << ":" << args << endl;
}
int main() {
// Test
ThreadPool *tp = new ThreadPool;
tp->init(5000);
for(int i=0; i<100; ++i) {
tp->add_event(test_proc, reinterpret_cast<void*>(i));
}
sleep(20);
tp->destroy();
return 0;
}
備註:本人編程新手,歡迎指出錯誤,多多指教!