Linux系统编程:线程池编程

文章目录

  • 1. 构成
    • 1.1 任务队列 `job_queue`
    • 1.2 工作线程 `worker`
    • 1.3 线程池 `thread_pool`
  • 2. 流程
  • 3. 实例

 为什么使用线程池?
     频繁创建和销毁线程浪费CPU资源
     
 线程是什么?
     一堆线程放在一个池子里统一管理

1. 构成

Linux系统编程:线程池编程_第1张图片类似于银行柜台的流程

1.1 任务队列 job_queue

作用: 存放待处理的任务

成员:

构成 接口
处理函数 void *(*)(void*)
参数 void *arg
队列指针 struct job_queue* pnext

1.2 工作线程 worker

作用: 处理任务

1.3 线程池 thread_pool

作用: 管理多个线程并提供任务队列的接口

成员:

构成 接口
初始化 threadpool_init()
销毁 threadpool_destroy()
添加任务 threadpool_add_job()

2. 流程

使用流程:

  1. 初始化线程池
  2. 向线程池添加任务
  3. 销毁线程池

线程池初始化:

  1. 初始化任务队列和工作线程组
  2. 将等候在条件变量(任务队列上有任务)上的一个线程唤醒并从该任务队列中取出第一个任务给该线程执行
  3. 等待任务队列中所有任务执行完毕

3. 实例

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

// 创建线程池
class ThreadPool{
        vector<thread> threads;         // 放线程
        queue<function<void()>> tasks;      // 放任务
        condition_variable cond;         // 条件变量
        mutex m;                   // 互斥锁
        bool exited = false;           // 退出标志
public:
        ThreadPool(int num){         // 构造函数
                for(int i=0;i<num;++i){
                        thread t( [this](){
                                while(true){
                                        function<void()> func;
                                        {
                                                unique_lock<mutex> lock(m);           // 加锁
                                                while(tasks.empty() && !exited) cond.wait(lock);      // 没有任务,等待
                                                if(exited) break;
                                                func = tasks.front();
                                                tasks.pop();
                                        }
                                        func();
                                }
                        } );
                        threads.emplace_back(move(t));        // 移动构造
                }
        }
        ~ThreadPool(){            // 析构函数
                exited = true;          // 标志置为退出
                cond.notify_all();           // 条件变量,通知所有
                for(auto& thread:threads){       // 回收
                        thread.join();
                }
        }
        ThreadPool(const ThreadPool&) = default;         // 拷贝构造函数去掉
        ThreadPool& operator=(const ThreadPool&) = default;     // 复制运算符重载去掉

        // 添加任务
        void AddTask(function<void()> func){
                lock_guard<mutex> guard(m);        // 加锁
                tasks.push(func);             // 把任务加到队列里面
                cond.notify_one();            // 条件变量,通知一个去工作
        }
};

int main(){
        auto test = [](){
                this_thread::sleep_for(2s);
                cout << this_thread::get_id() << " do somwthing..." << endl;
        };

        ThreadPool pool(5);                // 创建线程池

        for(int i=0;i<15;++i){             // 分配15个任务
                pool.AddTask(test);
        }
        this_thread::sleep_for(10s);
}

结果为:

[root@foundation1 C++7.17]# g++ threadpool.cpp -pthread
[root@foundation1 C++7.17]# ./a.out
140120258209536 do somwthing...
140120249816832 do somwthing...
140120241424128 do somwthing...
140120233031424 do somwthing...
140120266602240 do somwthing...
140120249816832140120258209536 do somwthing... do somwthing...

140120241424128 do somwthing...
140120266602240 do somwthing...
140120233031424 do somwthing...
140120241424128140120249816832 do somwthing...140120258209536 do somwthing...
 do somwthing...

140120266602240 do somwthing...
140120233031424 do somwthing...

你可能感兴趣的:(Linux系统编程,c++,linux系统编程)