博客
关于我
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.hpp和ThreadPool.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.hpp、ThreadPool.hpp和main.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/

    你可能感兴趣的文章
    Python:如果DataFrames之间的其他值匹配,则对DataFrame中的值求和
    查看>>
    Python:字典思维
    查看>>
    Python:将 HEX 字符串转换为字节
    查看>>
    Python:将列表与范围列表合并
    查看>>
    Python:将列表列表初始化为一定大小,
    查看>>
    Python:带有生成器的给定集合的幂集
    查看>>
    Python:按字符的位置拆分字符串
    查看>>
    Python:替换嵌套字典中的值
    查看>>
    Python:爬取数据出现response.status_code为403解决方法
    查看>>
    Python:爬取数据出现response.status_code为418解决方法
    查看>>
    Python:生成“元组集“;来自“元组列表“;不考虑顺序
    查看>>
    Python:生成具有趋势的随机时间序列数据(例如周期性、指数衰减等)
    查看>>
    Python:用渐进式数字重命名列表中的重复项而不对列表进行排序
    查看>>
    Python:矩形参数无效
    查看>>
    Python:语法进阶
    查看>>
    Python:调用复制函数时调用 Python 对象时超出了最大递归深度
    查看>>
    Python:这两个 import 语句有什么区别?
    查看>>
    Python:通过串口从 Velleman k8090 读取数据
    查看>>
    python:遍历具有列表值的字典
    查看>>
    Python:降低精度 pandas 时间戳数据帧
    查看>>