博客
关于我
C++11创建一个跨平台线程池
阅读量:165 次
发布时间:2019-02-26

本文共 2401 字,大约阅读时间需要 8 分钟。

实现一个简单的线程池

看完《Windows核心编程》的“线程池”这一章后,我只学到了几个Windows线程池相关的API,并没有深入了解线程池的实现细节。尤其是每次编写多线程任务时都手动管理线程,确实让人觉得有点手痒。后来想起了祁宇老师的《深入应用C++11》,在书中找到了一章关于“使用C++11实现一个线程池”的内容,于是按照书中的代码在VS下编写了一个简单的线程池,成功运行后倍感兴奋。

接着,我又开始思考,如果将这个纯C++实现的线程池放到Linux下,是否也能运行呢?于是,在Linux环境下尝试了一番,今天终于实现了!以下是我在VS2015和Linux g++5.4.0下实现线程池的整个过程。


线程池的实现原理

线程池的实现通常包括三层:同步服务层排队层异步服务层。这也是一种典型的生产者-消费者模式。具体来说:

  • 同步服务层:负责接收新任务,保证任务的安全性。
  • 排队层:作为一个同步队列,确保生产者和消费者能够安全地共享数据,同时防止任务数量无限制增长。
  • 异步服务层:由线程池预先创建的线程负责从排队层中取任务执行。

线程池还需要提供一个停止接口,让用户能够在需要时停止线程池的运行。


Windows平台运行

环境配置

  • 硬件:通过cmd运行systeminfo可以查看CPU信息。我的开发机上配备了Intel64 Family 6 Model 58 Stepping 9 GenuineIntel,四核处理器(通过Process Explorer查看cores数量)。
  • 软件:Windows10 X64 + VS2015。
  • 工程创建

  • 使用VS2015新建一个Win32 console工程,选择空项目,命名为ThreadPool
  • 从GitHub下载SyncQueue.hppThreadPool.hpp,并将这两个文件添加到项目中。
  • 添加一个main.cpp文件用于测试。由于没有找到合适的测试代码,我参考书中的内容并进行了修改。
  • #include "ThreadPool.hpp"int main() {    ThreadPool pool;    std::thread thd1([&pool] {        for (int i = 0; i < 10; ++i) {            auto thdId = this_thread::get_id();            pool.AddTask([thdId] {                cout << "同步层1 thread ID : " << thdId << endl;            });        }    });    std::thread thd2([&pool] {        for (int i = 0; i < 10; ++i) {            auto thdId = this_thread::get_id();            pool.AddTask([thdId] {                cout << "同步层2 thread ID : " << thdId << endl;            });        }    });    this_thread::sleep_for(std::chrono::seconds(2));    cout << "清空线程池..." << endl;    pool.Stop();    thd1.join();    thd2.join();    cout << "主线程已过..." << endl;    this_thread::sleep_for(std::chrono::seconds(5));    return 0;}

    运行效果

    运行后,会看到两个线程分别执行任务,输出各自的线程ID。线程池在停止后,所有线程也会正确退出。


    Linux平台运行

    环境配置

  • 我在VMware虚拟机上运行Ubuntu,环境参数如下:
    • CPU:Intel Cores数量(通过process explorer查看)
    • 操作系统:Ubuntu 16.04.2
  • 工程创建

  • 在Linux上创建一个文件夹ThreadPool,将SyncQueue.hppThreadPool.hppmain.cpp拷贝到该文件夹中。
  • 运行ls Threadpool可以确认文件是否存在。
  • 编译

  • 错误一:直接运行g++ -o Threadpool main.cpp,会报好几屏错误,提示没有选择C++11支持。
  • 错误二:加上-std=c++11后,仍然有错误,提示undefined reference to 'pthread_create'
  • 通过搜索关键词undefined reference to 'pthread_create',我了解到在Linux下,pthread不是默认库,需要在编译时添加-pthread选项。具体来说,新版的gcc需要使用-pthread,而旧版本可能需要-lpthread。经过测试,发现新版本的gcc确实需要-pthread


    最终编译命令

    g++ -std=c++11 -pthread -o Threadpool main.cpp

    运行./Threadpool后,会看到两个线程分别执行任务,输出各自的线程ID。线程池停止后,所有线程也会正确退出。


    总结

    通过这次项目,我对线程池有了更深入的理解,特别是C++11在多线程编程中的优势。将同一段代码从Windows转到Linux,过程中遇到的pthread库问题让我对Linux开发有了更深的印象。未来,我计划进一步优化线程池的性能和功能,比如增加线程池的可扩展性和任务优先级的支持。

    转载地址:http://mdqu.baihongyu.com/

    你可能感兴趣的文章
    NTP配置
    查看>>
    NUC1077 Humble Numbers【数学计算+打表】
    查看>>
    NuGet Gallery 开源项目快速入门指南
    查看>>
    NuGet(微软.NET开发平台的软件包管理工具)在VisualStudio中的安装的使用
    查看>>
    nuget.org 无法加载源 https://api.nuget.org/v3/index.json 的服务索引
    查看>>
    Nuget~管理自己的包包
    查看>>
    NuGet学习笔记001---了解使用NuGet给net快速获取引用
    查看>>
    nullnullHuge Pages
    查看>>
    NullPointerException Cannot invoke setSkipOutputConversion(boolean) because functionToInvoke is null
    查看>>
    null可以转换成任意非基本类型(int/short/long/float/boolean/byte/double/char以外)
    查看>>
    Number Sequence(kmp算法)
    查看>>
    Numix Core 开源项目教程
    查看>>
    numpy
    查看>>
    NumPy 库详细介绍-ChatGPT4o作答
    查看>>
    NumPy 或 Pandas:将数组类型保持为整数,同时具有 NaN 值
    查看>>
    numpy 或 scipy 有哪些可能的计算可以返回 NaN?
    查看>>
    numpy 数组 dtype 在 Windows 10 64 位机器中默认为 int32
    查看>>
    numpy 数组与矩阵的乘法理解
    查看>>
    NumPy 数组拼接方法-ChatGPT4o作答
    查看>>
    numpy 用法
    查看>>