linux c++下将pthread封装成threadpool(线程池)

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;
}


 


備註:本人編程新手,歡迎指出錯誤,多多指教!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值