系统编程七(线程池)

线程池实战案例

#include<iostream>
#include<queue>
#include<pthread.h>
#include<unistd.h>
using namespace std;

typedef void (*task_func_t)(void*);
typedef void* task_arg_t;
//任务类
class Task{
        task_func_t pfunc;      //任务函数
        task_arg_t parg;        //任务参数
public:
        Task(task_func_t func,task_arg_t arg):pfunc(func),parg(arg){}
        void Execute()const{
                pfunc(parg);
        }
};
//线程池
class ThreadPool{
        queue<Task> tasks;//任务队列
        pthread_t tids[6];//线程集合
        pthread_mutex_t mutex;//互斥量
		pthread_cond_t cond;//条件变量
        bool shutdown;
        //添加一个新任务,把一个线程叫醒
        //线程池退出时,叫醒所有线程并退出
public:
        ThreadPool():shutdown(false){
                pthread_mutex_init(&mutex,NULL);
                pthread_cond_init(&cond,NULL);
                for(auto& tid:tids){
                        pthread_create(&tid,NULL,(void*(*)(void*))&ThreadPool::routine,this);//强转为函数指针类型
                }
        }
        ThreadPool(const ThreadPool&) = delete;
        ThreadPool& operator=(const ThreadPool&) = delete;
        ~ThreadPool(){
                shutdown = true;//需要结束线程时将其置为true
                pthread_cond_broadcast(&cond);//这里叫醒所有线程来结束它
                for(auto tid:tids){
                        pthread_join(tid,NULL);
                }
        void AddTask(task_func_t func,task_arg_t arg){
                pthread_mutex_lock(&mutex);
                tasks.push(Task(func,arg));
                pthread_mutex_unlock(&mutex);
                pthread_cond_signal(&cond);//添加一个任务后,唤醒一个线程
        }
        static void* routine(void* arg){//线程执行任务函数
                ThreadPool* pool = (ThreadPool*)arg;
                for(;;){
                        pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock,&pool->mutex);//如果底下有线程退出,这里会收到信号释放锁
                        pthread_mutex_lock(&pool->mutex);
                        while(!pool->shutdown && pool->tasks.empty()){
                                pthread_cond_wait(&pool->cond,&pool->mutex);//无任务时,等待派发任务将线程阻塞,等待信号并释放锁
                        }
                        if(pool->shutdown && pool->tasks.empty()){
                                pthread_exit(NULL);     //线程退出      
                        }
                        Task task = pool->tasks.front();
                        pool->tasks.pop();
                        pthread_mutex_unlock(&pool->mutex);
                        task.Execute();
                        pthread_cleanup_pop(0);
                }
        }
};

void test(void* arg){
        cout << pthread_self() << ":" << (char*)arg << endl;
}

int main(){
        Task t(test,(task_arg_t)"Hello World");
        t.Execute();

        ThreadPool pool;
        pool.AddTask(test,(task_arg_t)"Hello1");
        pool.AddTask(test,(task_arg_t)"Hello2");
		pool.AddTask(test,(task_arg_t)"Hello3");
        pool.AddTask(test,(task_arg_t)"Hello4");
        pool.AddTask(test,(task_arg_t)"Hello5");
        pool.AddTask(test,(task_arg_t)"Hello6");
        pool.AddTask(test,(task_arg_t)"Hello7");
        pool.AddTask(test,(task_arg_t)"Hello8");
}

c++11实现:

#include <iostream>
#include <thread>
#include <mutex>
#include <queue>
#include <functional> //function
#include <condition_variable>
 
using namespace std;
 
class ThreadPool{
    typedef void (*task_func_t)(void*);
    typedef void* task_arg_t;
    queue<pair<task_func_t,task_arg_t>> tasks;// 任务队列
    vector<thread> threads;// 线程集合
    mutex m;
    condition_variable cv;
    bool shundown;
public:
    ThreadPool(int thread_num):shundown(false){
        for(int i=0;i<thread_num;++i){
            threads.push_back(thread([this]{ // routine
                 while(true){
                   // pair<task_func_t,task_arg_t> task;
                    task_func_t func = nullptr;
                    task_arg_t arg = nullptr;
                    {
                        unique_lock<mutex> lock(m);
                        cv.wait(lock,[this]{return shundown || !tasks.empty();}); 
                        if(shundown && tasks.empty()){
                            break;
                        } 
                        // task = tasks.front();
                        // func = task.first;
                        // arg = tasks.second;
                        tie(func,arg) = tasks.front();
                        tasks.pop();
                    }
                    func(arg);
                    //task.first(task.second);
                 }                   
            }));
        }
    }
    ThreadPool(const ThreadPool&) = delete;
    ThreadPool& operator=(const ThreadPool&) = delete;
    ~ThreadPool(){
        shundown = true;
        cv.notify_all();
        for(auto& thread:threads){
            thread.join();
        }
    }
    void AddTask(task_func_t func,task_arg_t arg){
        unique_lock<mutex> lock(m);
        //tasks.push(pair<task_func_t,task_arg_t>(func,arg));
        //tasks.push(make_pair(func,arg));
        //tasks.push({func,arg}); // C++11
        tasks.emplace(func,arg); // C++11
        cv.notify_one();
    }
};
 
template <typename T,typename S>
pair<T,S> make_pair(T& a,S& b){
    return pair<T,S>(a,b);
}
 
struct Data{
    mutex m;
    int n;
};
void func(void* n){
    Data* d = (Data*)n;
    {
        unique_lock<mutex> lock(d->m);
        cout<< this_thread::get_id() << ":" <<++(d->n) << endl;
    }
    this_thread::sleep_for(100ms);
}
struct Functor{
   void operator()(void* n){
        func(n); 
   }
};
 
int main(){
    // 函数指针、lamdba表达式、函数对象统称为可调用对象(callable object)
    function<void(void*)> pf = func;
    function<void(void*)> lamdba = [](void* n){ func(n);};
    function<void(void*)> functor = Functor();
 
    Data data;
    data.n = 0;
 
    pf(&data);
    lamdba(&data);
    functor(&data);
 
    return 0;
 
    ThreadPool pool(4);
    this_thread::sleep_for(100ms);
    
 
    for(int i=0;i<10;++i){
        pool.AddTask(func,&data);
    }
}

c++11实现(改进版):

#include <iostream>
#include <thread>
#include <mutex>
#include <queue>
#include <functional> //function
#include <condition_variable>
 
using namespace std;
 
class ThreadPool{
    // typedef void (*task_func_t)(void*);
    typedef function<void(void*)> task_func_t;
    typedef void* task_arg_t;
    queue<pair<task_func_t,task_arg_t>> tasks;// 任务队列
    vector<thread> threads;// 线程集合
    mutex m;
    condition_variable cv;
    bool shundown;
public:
    void routine(){
            while(true){
             // pair<task_func_t,task_arg_t> task;
                task_func_t func = nullptr;
                task_arg_t arg = nullptr;
                {
                    unique_lock<mutex> lock(m);
                    cv.wait(lock,[this]{return shundown || !tasks.empty();}); 
                    if(shundown && tasks.empty()){
                        break;
                     } 
                     // task = tasks.front();
                     // func = task.first;
                     // arg = tasks.second;
                   tie(func,arg) = tasks.front();
                   tasks.pop();
               }
               func(arg);
               //task.first(task.second);
          }                   
    }
    ThreadPool(int thread_num):shundown(false){
        for(int i=0;i<thread_num;++i){
            threads.push_back(thread([this]{ // routine
               routine();
            }));
        }
    }
    ThreadPool(const ThreadPool&) = delete;
    ThreadPool& operator=(const ThreadPool&) = delete;
    ~ThreadPool(){
        shundown = true;
        cv.notify_all();
        for(auto& thread:threads){
            thread.join();
        }
    }
    void AddTask(task_func_t func,task_arg_t arg){
        unique_lock<mutex> lock(m);
        //tasks.push(pair<task_func_t,task_arg_t>(func,arg));
        //tasks.push(make_pair(func,arg));
        //tasks.push({func,arg}); // C++11
        tasks.emplace(func,arg); // C++11
        cv.notify_one();
    }
};
 
template <typename T,typename S>
pair<T,S> make_pair(T& a,S& b){
    return pair<T,S>(a,b);
}
 
struct Data{
    mutex m;
    int n;
};
void func(void* n){
    Data* d = (Data*)n;
    {
        unique_lock<mutex> lock(d->m);
        cout<< this_thread::get_id() << ":" <<++(d->n) << endl;
    }
    this_thread::sleep_for(100ms);
}
struct Functor{
   void operator()(void* n){
        func(n); 
   }
};
 
int main(){
   /*
    // 函数指针、lamdba表达式、函数对象统称为可调用对象(callable object)
    function<void(void*)> pf = func;
    function<void(void*)> lamdba = [](void* n){ func(n);};
    function<void(void*)> functor = Functor();
 
    pf(&data);
    lamdba(&data);
    functor(&data);
 
    return 0;
*/
    Data data;
    data.n = 0;
 
    ThreadPool pool(4);
    this_thread::sleep_for(100ms);
    
 
    for(int i=0;i<10;++i){
        pool.AddTask([](void*n){func(n);},&data);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值