博客
关于我
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/

    你可能感兴趣的文章
    nio 中channel和buffer的基本使用
    查看>>
    NIO基于UDP协议的网络编程
    查看>>
    NISP一级,NISP二级报考说明,零基础入门到精通,收藏这篇就够了
    查看>>
    Nitrux 3.8 发布!性能全面提升,带来非凡体验
    查看>>
    NI笔试——大数加法
    查看>>
    NLog 自定义字段 写入 oracle
    查看>>
    NLog类库使用探索——详解配置
    查看>>
    NLP 基于kashgari和BERT实现中文命名实体识别(NER)
    查看>>
    NLP 项目:维基百科文章爬虫和分类【01】 - 语料库阅读器
    查看>>
    NLP_什么是统计语言模型_条件概率的链式法则_n元统计语言模型_马尔科夫链_数据稀疏(出现了词库中没有的词)_统计语言模型的平滑策略---人工智能工作笔记0035
    查看>>
    NLP学习笔记:使用 Python 进行NLTK
    查看>>
    NLP的神经网络训练的新模式
    查看>>
    NLP采用Bert进行简单文本情感分类
    查看>>
    NLP问答系统:使用 Deepset SQUAD 和 SQuAD v2 度量评估
    查看>>
    NLP:使用 SciKit Learn 的文本矢量化方法
    查看>>
    Nmap扫描教程之Nmap基础知识
    查看>>
    Nmap端口扫描工具Windows安装和命令大全(非常详细)零基础入门到精通,收藏这篇就够了
    查看>>
    NMAP网络扫描工具的安装与使用
    查看>>
    NMF(非负矩阵分解)
    查看>>
    nmon_x86_64_centos7工具如何使用
    查看>>