线程池的封装与实现

#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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值