基于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日

相关文章

  • 浅谈Redis高并发缓存架构性能优化实战

    浅谈Redis高并发缓存架构性能优化实战 一、前言 随着互联网的发展,访问量的激增,如何提高网站的响应速度,增加网站的并发能力成为了大家关注的热点。而Redis作为高性能缓存数据库,成为了缓存业务的首选。 在实际开发中,Redis高并发缓存架构的性能优化是非常重要的,本文将结合实战经验,浅谈Redis高并发缓存架构性能优化的几个方面。 二、Redis高并发缓…

    多线程 2023年5月17日
    00
  • Java并发编程数据库与缓存数据一致性方案解析

    Java并发编程数据库与缓存数据一致性方案解析 需要解决的问题 在Web应用中,数据通常存储在数据库中,为了提高读取速度,还会加入缓存机制。这就引出了一个问题:如何保证数据库与缓存中的数据一致性? 解决方案 1. 读取时双重检查 在读取缓存数据时,先从缓存中读取,如果缓存不存在,则从数据库中读取,并将数据存储到缓存中。这里需要注意的是,为了防止在读取缓存数据…

    多线程 2023年5月16日
    00
  • Java并发编程之重入锁与读写锁

    Java并发编程之重入锁与读写锁 什么是锁 在多线程编程中,为了保证多线程之间数据的一致性和正确性,我们常常需要对共享数据进行加锁处理,以避免出现竞态条件(Race condition)导致的数据错误或程序崩溃等问题。锁是一个非常重要的多线程并发编程工具。 Lock接口 在Java中,锁的实现是通过java.util.concurrent.locks包中的L…

    多线程 2023年5月17日
    00
  • java利用Future实现多线程执行与结果聚合实例代码

    下面我为你详细解析如何利用Java的Future实现多线程执行以及结果聚合的实例代码。 一、Future的概述 Java中的Future表示一个异步计算任务,是构建异步应用程序的基础。它提供了在处理多线程计算结果时的Java编程接口,可以用于指示多线程计算是否完成,获取计算的结果,并且可以取消计算。 二、FutureTask的使用 在Java中,Future…

    多线程 2023年5月16日
    00
  • 详谈Java多线程的几个常用关键字

    接下来我将详细讲解“详谈Java多线程的几个常用关键字”。 一、Java多线程的几个常用关键字 Java中的多线程是通过Thread类及Runnable接口来实现的。在Java多线程中,有几个常用关键字需要熟知,如下所示: synchronized:用于实现同步,防止并发访问共享数据发生错误,并且保证了多线程的协调运行。 volatile:用于保证可见性和禁…

    多线程 2023年5月17日
    00
  • 详细分析Java并发集合ArrayBlockingQueue的用法

    下面是详细的攻略: Java并发集合ArrayBlockingQueue的用法分析 1. 简介 ArrayBlockingQueue是Java中的一个并发集合,是线程安全的,可以在生产者和消费者之间传递数据。它是一个有界队列,具有固定的大小,即在构造时指定队列的容量。 2. 常用方法 ArrayBlockingQueue有许多常用的方法,下面是其中的一些: …

    多线程 2023年5月16日
    00
  • Java多线程之搞定最后一公里详解

    Java多线程之搞定最后一公里详解 简介 多线程是Java重要的特性之一,它可以使程序变得更加高效和快速,提升用户体验。对于Java开发者来说,不了解多线程的相关概念和技术点就无法达到高超的开发水平。本篇文章主要讲解Java多线程的最后一公里,即如何处理并发的关键问题。 如何处理并发关键问题 1. 竞态条件 竞态条件是多线程编程中最常见的问题之一。它所指的是…

    多线程 2023年5月17日
    00
  • C++ 线程(串行 并行 同步 异步)详解

    C++ 线程详解 C++ 中的线程是一种基于同步和异步的编程模型,可以帮助程序员更好地利用 CPU 和内存资源,提高程序性能。本篇文章将详细讲解C++ 线程的概念、分类以及用法。 线程概念 一个线程是程序执行中的单一线路,每个线程都有自己的指令计数器、栈空间和寄存器等,并同时访问共同的全局数据。C++ 中线程的作用和进程类似,一个进程包含多个线程,每个线程可…

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