C++(27): 线程池

目录

1. 概述

2. 例程

(1)ThreadPool.h

(2)ThreadPool.cpp

(3)Start.cpp

(4)编译


1. 概述

线程池技术绝不是C++独有的,Java和Python都有比较晚完善的线程池构造接口。

通俗的讲,线程池只是一种管理线程的方式。很多时候,我们为了充分利用CPU和Memory资源,会创建一些独立的线程,执行同步或异步的任务。但有一个不得不考虑的问题是,现成的创建和销毁本身也是消耗系统资源的,尤其是一些需要频繁创建和销毁线程的应用场景下。当然有时候有一些连续的任务也不需要通过线程池技术来完成。

如上所述,为了避免频繁创建和销毁线程带来的系统资源的消耗,我们可以提前创建一定数量的线程,用来等待和处理队列中的事务,无需反复地创建和销毁线程。

2. 例程

(1)ThreadPool.h

#ifndef __THREADPOOL_H__

#define __THREADPOOL_H__


#include <iostream>  

#include <vector>  

#include <queue>  

#include <thread>  

#include <mutex>  

#include <condition_variable>  

#include <future>

#include <functional>

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <stdint.h>

 

class ThreadPool

{

public:  

    ThreadPool(size_t threads);

 

    template<class F, class... Args>  

    auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type>

    {

        using return_type = typename std::result_of<F(Args...)>::type;  

 

        auto task = std::make_shared<std::packaged_task<return_type()>>(  

            std::bind(std::forward<F>(f), std::forward<Args>(args)...)  

        );  

 

        std::future<return_type> res = task->get_future();  

        {  

            std::unique_lock<std::mutex> lock(queueMutex);  

 

            if (stop) {  

                throw std::runtime_error("enqueue on stopped ThreadPool");  

            }  

 

            tasks.emplace([task]() { (*task)(); });  

        }  

 

        condition.notify_one();  

        return res;  

    }

 

    ~ThreadPool();

 

private:  

    std::vector<std::thread> workers;  

    std::queue<std::function<void()>> tasks;  

 

    std::mutex queueMutex;  

    std::condition_variable condition;  

    bool stop;  

};

#endif ///< __THREADPOOL_H__

(2)ThreadPool.cpp

#include "ThreadPool.h"


ThreadPool::ThreadPool(size_t threads) : stop(false)

{

    for (size_t i = 0; i < threads; ++i) {  

        workers.emplace_back([this] {  

            while (true) {  

                std::function<void()> task;  

                {  

                    std::unique_lock<std::mutex> lock(this->queueMutex);  

                    this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });  

                    if (this->stop && this->tasks.empty()) {  

                        return;  

                    }  

                    task = std::move(this->tasks.front());  

                    this->tasks.pop();  

                }  

                task();  

            }  

        });  

    }  

}

 

ThreadPool::~ThreadPool()

{  

    {  

        std::unique_lock<std::mutex> lock(queueMutex);  

        stop = true;  

    }  

    condition.notify_all();  

    for (std::thread &worker : workers) {  

        worker.join();  

    }  

}  

(3)Start.cpp

#include <iostream>  

#include <vector>  

#include <queue>  

#include <thread>  

#include <mutex>  

#include <condition_variable>  

#include <future>

#include <functional>

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <stdint.h>

#include "ThreadPool.h"


/** sudo g++ -std=c++17 -o ./Start.bin ./*.cpp -lpthread */


#define EXTERNAL_FUNC 0 ///< 0: 类内部成员

                        ///< 1: 类外部成员

#if EXTERNAL_FUNC == 1

// 定义一个返回整数的函数  

int intFunction(int x)

{

    return x * x;

}  

// 定义一个返回字符串的函数  

std::string stringFunction(std::string s)

{

    return s + " world";

}

 

int main(int argc, char* argv[])

{

    ThreadPool pool(4);  

    // 使用enqueue来执行intFunction,传入参数4  

    auto result1 = pool.enqueue(intFunction, 4);  

 

    // 使用enqueue来执行stringFunction,传入参数"hello"  

    auto result2 = pool.enqueue(stringFunction, "hello");  

 

    // 获取并打印结果  

    std::cout << "result1: " << result1.get() << std::endl;  // 应该打印出16  

    std::cout << "result2: " << result2.get() << std::endl;  // 应该打印出"hello world"  

 

    return 0;  

}

#else ///< 作为类成员

class DemoClass

{

public:  

    DemoClass(int num_threads = 1)

    {

        if(num_threads <= 0 ){

            num_threads = 1;

        }

        pool = new ThreadPool(num_threads);

    }

    ~DemoClass()

    {

        delete pool;

        pool = nullptr;

    }

    void printTask(int n)

    {  

        std::cout << "Processing " << n << std::endl;

    }  

    void startProcessing()

    {

        for (int i = 1; i <= 50; ++i){

            pool->enqueue(&DemoClass::printTask, this, i);

            usleep(1); ///< 短暂的等待是有必要的.

        }  

    }

private:

    ThreadPool* pool = nullptr;

};  

int main(int argc, char* argv[])

{

    DemoClass myClass(10);  

    myClass.startProcessing();  

    return 0;  

}

#endif

(4)编译

sudo g++ -std=c++17 -o ./Start.bin ./*.cpp -lpthread

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值