C++线程池的简单实现方法

C++线程池是一种常用的并发编程技术,它允许我们创建一组固定数量的线程并维护它们,以便在需要时可以立即使用它们来执行任务。下面是一个C++线程池的简单实现方法:

  1. 定义任务队列

首先,我们需要定义一个任务队列,用于存储等待执行的任务。任务队列可以是一个简单的std::queue对象,用于存储任务函数。

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

这里使用了std::function对象来存储要执行的任务函数,以便可以存储任意类型的函数。

  1. 定义线程池类

接下来,我们需要定义一个线程池类,用于创建和管理线程池。线程池类应该包含一个std::vector对象,用于存储所有的线程对象。线程池初始化时应该创建并启动所有的线程,每个线程应该不断地从任务队列中获取任务并执行。

class ThreadPool {
public:
    explicit ThreadPool(int numThreads) : stop(false) {
        for (int i = 0; i < numThreads; ++i) {
            workers.emplace_back(
                [this] {
                    while (true) {
                        std::function<void()> task;
                        {
                            std::unique_lock<std::mutex> lock(queueMutex);
                            condition.wait(lock, [this] { return stop || !taskQueue.empty(); });
                            if (stop && taskQueue.empty())
                                return;
                            task = std::move(taskQueue.front());
                            taskQueue.pop();
                        }
                        task();
                    }
                }
            );
        }
    }

    template<class F>
    void enqueue(F f) {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            taskQueue.emplace(f);
        }
        condition.notify_one();
    }

    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            stop = true;
        }
        condition.notify_all();
        for (std::thread& worker : workers) {
            worker.join();
        }
    }

private:
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> taskQueue;

    std::mutex queueMutex;
    std::condition_variable condition;
    bool stop;
};

这里的ThreadPool类包含了enqueue()方法,用于向任务队列中添加新的任务函数。当一个新的任务函数添加到队列中后,我们要通知一个线程来执行这个任务。

  1. 创建线程池并执行任务

下面是一个简单的示例,展示如何创建一个ThreadPool对象,并在线程池中执行一些任务:

int main() {
    ThreadPool pool(4);
    for (int i = 0; i < 8; ++i) {
        pool.enqueue([] {
            std::cout << "Hello, world!\n";
        });
    }
    return 0;
}

这个示例中,首先创建一个ThreadPool对象,其将由4个线程处理任务。然后我们将8个任务添加到ThreadPool对象中,并在每个任务中打印“Hello, world!”。

  1. 示例2:用线程池计算斐波那契数列

下面是另一个示例,演示如何将线程池用于计算斐波那契数列。我们将使用递归的方式计算斐波那契数列,然后将计算过程分解为多个任务,将这些任务提交给线程池进行计算。

#include <iostream>
#include <chrono>
#include "ThreadPool.h"

int fib(int n) {
    if (n <= 1) {
        return n;
    } else {
        return fib(n - 1) + fib(n - 2);
    }
}

int main() {
    const int n = 40;
    ThreadPool pool(4);
    auto start = std::chrono::high_resolution_clock::now();
    auto fibFuture = pool.enqueue([&] { return fib(n); });
    auto result = fibFuture.get();
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double, std::milli> duration = end - start;
    std::cout << "Fibonacci(" << n << ") = " << result << "\n";
    std::cout << "Calculated in " << duration.count() << " milliseconds\n";
    return 0;
}

这次我们创建了ThreadPool对象,使用4个线程进行计算任务。在主函数中,我们通过递归方式计算斐波那契数列,然后将该计算分解为一个任务提交给线程池进行计算。最后,我们通过std::future对象获取结果,并打印出计算时间和结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++线程池的简单实现方法 - Python技术站

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

相关文章

  • Golang json 库中的RawMessage功能原理

    完整攻略:Golang json 库中的 RawMessage 功能原理 1. RawMessage是什么 在Golang中,RawMessage 是一个预定义类型,它用于存储任意未经处理的 JSON 数据。 它允许我们将复杂的任意 JSON 对象作为struct中的一部分而不必定义对应的struct。 2. RawMessage的使用方法 2.1 Unma…

    C 2023年5月23日
    00
  • c语言中getch,getche,getchar的区别

    当你在使用 C 语言编写控制台程序时,可能会使用到三个常用的函数:getch、getche和getchar。它们都可以用于从控制台读取用户输入的字符,但是它们的行为有些不同。 1. getch getch函数通常被用于读取单个字符,但是它是一个非标准的函数,不是ANSI C标准的一部分。因此,它的行为可能因操作系统/编译器而异。简单来说,它可以从键盘上读取一…

    C 2023年5月30日
    00
  • C语言实现2048游戏代码

    C语言实现2048游戏代码攻略 一、项目背景 2048游戏是一款非常经典且受欢迎的益智类游戏,目前已经在各个平台上得到广泛的应用。实现2048游戏的过程既可以锻炼编程基础功底,还能提高逻辑思维能力。因此,本项目旨在利用C语言实现2048游戏代码,供初学者参考与学习。 二、实现步骤 1. 初始化棋盘 首先,我们需要在C语言中创建一个数组,并将所有元素初始化为0…

    C 2023年5月23日
    00
  • C语言数据的存储超详细讲解中篇练习

    我会为你详细讲解“C语言数据的存储超详细讲解中篇练习”的完整攻略。 攻略概述 “C语言数据的存储超详细讲解中篇练习”主要是讲解C程序中变量和数组的内存模型,以及指针和函数在内存中的存储方式等。该练习主要包含以下部分: C语言中的内存模型 变量和数组的内存模型 指针在内存中的存储方式 函数在内存中的存储方式 示例练习题 在学习这篇练习时,你将会获得对C语言内存…

    C 2023年5月22日
    00
  • iOS读写json文件的方法示例

    在这里我将为你展示“iOS读写json文件的方法示例”的完整攻略,包括基本概念、操作步骤、示例代码和执行结果等方面的内容。 基本概念 在开始讲述攻略之前,我们需要了解一些基本概念: JSON:是一种轻量级的数据交换格式,具有可读性、易于解析和生成等特点。 JSON文件:是以JSON格式编写的文件,通常用于数据存储和传输。 操作步骤 想要在iOS中实现读写JS…

    C 2023年5月23日
    00
  • 基于malloc与free函数的实现代码及分析

    实现动态内存的分配和释放是C/C++程序中常见的问题。malloc和free函数是C/C++语言的标准库函数,用于动态分配和释放内存。本攻略将详细讲解基于malloc和free函数的动态内存分配和释放的实现方法及分析。 一、malloc函数的实现 在C/C++程序中,动态内存分配的过程通常由malloc函数实现。malloc函数的基本原理是向操作系统请求一定…

    C 2023年5月24日
    00
  • C语言实现系统关机注销功能

    实现C语言的系统关机和注销功能可以通过Windows API函数实现。在Windows平台下,可以使用ExitWindowsEx函数实现关机操作,使用LockWorkStation函数实现注销操作。 下面是实现关机功能的完整攻略: 在代码中包含Windows.h头文件,这个头文件包含了Windows API函数的定义。 #include <Window…

    C 2023年5月23日
    00
  • C/C++程序编译流程详解

    下面是对于“C/C++程序编译流程详解”的完整攻略: 概述 程序编译是将程序源代码转换为计算机可识别的机器码的过程。在C/C++语言中,程序编译分为四个主要阶段: 预处理(Preprocessing):处理以“#”开头的预处理指令; 编译(Compilation):将预处理后的文件转换为汇编文件; 汇编(Assembly):将汇编文件转换为机器码文件; 链接…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部