基于C++11的threadpool线程池(简洁且可以带任意多的参数)

基于C++11的threadpool线程池(简洁且可以带任意多的参数)

介绍

线程池是一种并发编程中提高性能与效率的技术,可以避免频繁创建和销毁线程,提升程序运行效率。本文将介绍基于C++11的线程池实现,并且可以传递任意多的参数。

实现

线程池主要由任务队列和线程池管理器两个部分组成。线程池管理器主要用来创建、销毁线程和管理任务队列,线程池中的任务队列存储着需要执行的任务。下面是线程池的详细实现过程:

  1. 首先需要定义一个任务队列:
std::queue<std::function<void()>> task_queue;
std::mutex task_mutex;
std::condition_variable task_cv;
int running_threads = 0;
  1. 定义一个添加任务的函数:
template<typename F, typename... Args>
void add_task(F&& f, Args&&... args)
{
    auto task = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
    std::unique_lock<std::mutex> lock(task_mutex);
    task_queue.push(std::move(task));
    task_cv.notify_one();
}
  1. 定义一个线程池管理器,用于创建、销毁线程和管理任务队列:
class ThreadPool
{
private:
    std::vector<std::thread> threads;
    int num_threads;
    bool stop;

public:
    ThreadPool(int num_threads) : num_threads(num_threads), stop(false)
    {
        for (int i = 0; i < num_threads; i++)
        {
            threads.emplace_back([this]()
            {
                while (true)
                {
                    std::function<void()> task;

                    {
                        std::unique_lock<std::mutex> lock(task_mutex);

                        task_cv.wait(lock, [this]()
                        {
                            return stop || !task_queue.empty();
                        });

                        if (stop && task_queue.empty())
                        {
                            break;
                        }

                        task = std::move(task_queue.front());
                        task_queue.pop();
                    }

                    running_threads++;

                    task();

                    running_threads--;

                    task_cv.notify_all();
                }
            });
        }
    }

    ~ThreadPool()
    {
        {
            std::unique_lock<std::mutex> lock(task_mutex);
            stop = true;
        }

        task_cv.notify_all();

        for (auto& thread : threads)
        {
            thread.join();
        }
    }
};
  1. 最后可以用下面的方式添加任务到线程池:
ThreadPool thread_pool(4);

// 添加一个不带参数的任务
thread_pool.add_task([]() {
    std::cout << "Task 1" << std::endl;
});

// 添加带参数的任务
int a = 1;
std::string b = "abc";
thread_pool.add_task([a, b]() {
    std::cout << "Task 2" << std::endl;
    std::cout << "a: " << a << std::endl;
    std::cout << "b: " << b << std::endl;
});

示例

示例一

#include <iostream>
#include "threadpool.h"

void print(int num)
{
    for (int i = 0; i < num; i++)
    {
        std::cout << "Thread " << std::this_thread::get_id() << ": " << i << std::endl;
    }
}

int main()
{
    ThreadPool thread_pool(4);

    for (int i = 0; i < 4; i++)
    {
        thread_pool.add_task(print, 10);
    }

    return 0;
}

上述代码中,首先创建一个线程池,然后向线程池中添加4个打印任务,每个任务打印10条信息。运行结果如下:

Thread 140599199620864: 0
Thread 140599207013568: 0
Thread 140599199620864: 1
Thread 140599200729344: 0
Thread 140599199620864: 2
Thread 140599207013568: 1
Thread 140599199620864: 3
Thread 140599207013568: 2
Thread 140599199620864: 4
Thread 140599200729344: 1
Thread 140599207013568: 3
Thread 140599199620864: 5
Thread 140599200729344: 2
Thread 140599207013568: 4
Thread 140599200729344: 3
Thread 140599199620864: 6
Thread 140599207013568: 5
Thread 140599199620864: 7
Thread 140599200729344: 4
Thread 140599199620864: 8
Thread 140599207013568: 6
Thread 140599199620864: 9
Thread 140599200729344: 5
Thread 140599207013568: 7
Thread 140599200729344: 6
Thread 140599207013568: 8
Thread 140599200729344: 7
Thread 140599207013568: 9
Thread 140599200729344: 8
Thread 140599200729344: 9

示例二

#include <iostream>
#include "threadpool.h"

int add(int a, int b)
{
    std::cout << "Thread " << std::this_thread::get_id() << ": " << a << "+" << b << "=" << a + b << std::endl;
    return a + b;
}

std::string concat(std::string a, std::string b)
{
    std::cout << "Thread " << std::this_thread::get_id() << ": " << a << "+" << b << "=" << a + b << std::endl;
    return a + b;
}

int main()
{
    ThreadPool thread_pool(4);

    int result1 = thread_pool.add_task(add, 1, 2).get();

    std::string result2 = thread_pool.add_task(concat, "hello", "world").get();

    std::cout << "Result1: " << result1 << std::endl;
    std::cout << "Result2: " << result2 << std::endl;

    return 0;
}

上述代码中,首先创建一个线程池,然后向线程池中添加两个任务,分别是计算两个整数的和和拼接两个字符串。最后获取任务的执行结果,并打印出来。运行结果如下:

Thread 140732506105856: 1+2=3
Thread 140732505235200: hello+world=helloworld
Result1: 3
Result2: helloworld

总结

本文介绍了基于C++11的线程池的实现方式,并且可以传递任意多的参数。线程池的实现主要包括任务队列和线程池管理器两个部分。最后给出了两个使用线程池的示例。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于C++11的threadpool线程池(简洁且可以带任意多的参数) - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • MySQL学习之事务与并发控制

    MySQL学习之事务与并发控制 什么是事务 数据库事务(Transaction)是指作为单个逻辑工作单元执行的一组数据库操作,这组操作要么全部执行,要么全部不执行,被视为一个不可分割的工作单元。 通常,一个事务包含了一组对数据库的读/写操作。在计算机领域,事务通常被用于保证数据的完整性,例如在转账时涉及到的两个操作“扣款”和“存款”,需要保证这两个操作要么全…

    多线程 2023年5月16日
    00
  • python实现多线程的方式及多条命令并发执行

    Python 是一门支持多线程操作的语言,多线程操作可以提高代码的执行效率,而且在处理多任务的情况下也比较常用。下面是 Python 实现多线程的方式及多条命令并发执行的完整攻略。 Python 实现多线程的方式 Python 实现多线程通常有以下三种方式: 1. 使用 _thread 模块实现多线程 使用 _thread 模块实现多线程需要注意的事项: 线…

    多线程 2023年5月16日
    00
  • 使用Redis解决高并发方案及思路解读

    使用Redis解决高并发方案及思路解读 高并发场景下,常常采用Redis作为数据缓存解决方案,以提升系统性能。以下是使用Redis解决高并发的思路和具体实现。 思路 在高并发场景下,系统会面临大量的请求,如果每个请求都直接访问数据库,会对数据库造成极大的压力。而使用Redis缓存能够让系统吞吐量更高,并减轻数据库的负担。具体思路如下: 当系统处理请求时,首先…

    多线程 2023年5月16日
    00
  • 阿里常用Java并发编程面试试题总结

    阿里常用Java并发编程面试试题总结是一份非常全面且重要的Java并发编程面试试题汇总,下面是一个完整的攻略: 1. 理解Java内存模型 Java内存模型是Java中并发编程的关键。在Java内存模型中,每个线程都会有自己的本地工作内存,同时所有线程都可以访问共享内存,这个共享内存指的是主内存。Java内存模型的主要作用是规定了线程如何与主内存交互,以及线…

    多线程 2023年5月16日
    00
  • Java进阶必备之多线程编程

    Java进阶必备之多线程编程攻略 在Java编程中,多线程编程是一项重要的技能。多线程编程可以提高程序的并发性和效率,使程序具有更好的响应性和用户体验。 1. 必备知识点 在进行多线程编程之前,您需要掌握以下重要的知识点: 1.1 线程的生命周期 Java中的线程具有生命周期。线程的生命周期包括以下几个状态: 新建状态(New):当创建了一个线程对象后,该线…

    多线程 2023年5月17日
    00
  • springboot+websocket实现并发抢红包功能

    一、前言 在现在的Web应用开发中,实时性的需求越来越高,一种常见的技术就是WebSocket。WebSocket是HTML5中新增的协议,可以实现客户端和服务端的全双工通信,而不需要像HTTP那样每次请求后都要断开连接。 Spring Boot是一个基于Spring框架的Web应用开发框架,可以构建独立的、生产级别的Spring应用程序,简化了Spring…

    多线程 2023年5月16日
    00
  • Java 浅谈 高并发 处理方案详解

    Java浅谈高并发处理方案详解 前言 随着互联网的发展和用户访问量的逐步增加,高并发逐渐成为互联网开发中的常见问题。而 Java 作为一门流行的编程语言,其处理高并发问题的方案也备受关注。本篇文章将浅谈 Java 高并发处理方案,并且给出两个对高并发处理方案的具体示例。 常用的高并发处理方案 多线程 多线程是 Java 中常用的高并发解决方案。可以通过创建多…

    多线程 2023年5月16日
    00
  • Yii+MYSQL锁表防止并发情况下重复数据的方法

    在 Yii 中,我们可以使用 MYSQL 锁表的方式来防止并发情况下重复数据的产生。下面是完整攻略的步骤: 步骤一:准备工作 在开始之前,确保已经完成了以下准备工作: 已经安装好了 Yii 框架以及 MYSQL 数据库 有相应的表格需要进行锁定 步骤二:检查并发情况下的数据重复 在进行 MYSQL 锁表之前,必须先检查并发情况下的数据重复。可以通过以下方法实…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部