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

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

    看完《Windows核心编程》的“线程池”这一章后,仅仅是学到了几个Windows线程池相关的API的,并没有触及到线程池是如何实现的这个层次,总感觉意犹未尽,特别手痒,想要自己实现一个简单的线程池。偶然的,想起了之前买的祁宇老师的《深入应用C++11》中,有一章介绍“使用C++11实现一个线程池”,于是按照原书敲了一顿代码,在VS下顺利运行起来了,兴奋不已。然后,再深入一想,既然是纯C++实现的线程池,那么放到Linux下,也是可以运行的,于是又动手在Linux下折腾了一番,今日终于也运行起来了,特此记录,分享整个折腾过程。

一、线程池

    本文主要介绍我在VS2015和Linux g++5.4.0下构建工程、编译和调试的过程,线程池的实现原理和代码解析,大家可以直接去看祁宇老师的书。但是,为免得突兀,我还是摘抄一部分原理如下:

    一个完整的线程池包括三层:同步服务层、排队层和异步服务层,其实这也是一种生产者-消费者模式,同步层是生产者,不断将新任务丢到排队层中,因此,线程池需要提供一个添加新任务的接口供生产者使用;消费者是异步层,具体是有线程池中预先创建的线程去处理排队层中的任务。排队层是一个同步队列,它内部保证了上下两层对共享数据的安全访问,同时还要保证队列不会被无限制地添加任务导致内存暴涨。另外,线程池还要提供一个停止接口,让用户能够在需要的时候停止线程池的运行。

二、Windows平台运行

1,环境

1)硬件

    通过cmd->systeminfo可以查看CPU信息

    Intel64 Family 6Model 58 Stepping 9 GenuineIntel ~3201

    它是一个四核处理器(通过process explorer -> system information,可以看到cores的数量)

2)软件

    win10 X64 + VS2015

2,工程创建

1)使用VS2015新建一个win32 console工程,选择空项目,命名为Threadpool,其他默认即可。

2)https://github.com/qicosmos/cosmos下载SyncQueue.hpp和ThreadPool.hpp,并添加进该工程。

3)添加一个main.cpp文件,用于测试。该文件由于没能在github上找到,我是照书抄的,并修改了书中的一处明显bug。如下:

#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 << "syn layer1 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 << "syn layer2 thread ID : " << thdId << endl;			});		}	});	this_thread::sleep_for(std::chrono::seconds(2));	//getchar();	cout << "clear thread pool..." << endl;	pool.Stop();	thd1.join();	thd2.join();	cout << "main thread is over..." << endl;	this_thread::sleep_for(std::chrono::seconds(5));    return 0;}

注:

1)书中在测试函数中,有这么两行代码:

ThreadPool pool;	pool.start(2);
    事实上,start()函数是私有的,不可直接调用。另外,如果需要开指定次数的线程,直接在构造函数中传参即可,无须多次一举。

2)关于.hpp和.h的区别,可以参考博客http://blog.csdn.net/zhaojunshi886/article/details/5856175

    简单来说,.hpp适合库文件,特别是模板库。

3)C++11的线程对象,以及线程对象的stop和join函数,和python的多线程库非常相似,看来C++有向更高级编程语言靠齐的趋势。

3,运行效果

三、Linux平台运行

1,环境

    我是在VMware虚拟机上运行的ubuntu,环境参数如下图

2,构建工程

    在Linux上构建c++工程就简单了,直接新建一个文件夹“Threadpool”,将上面的三个文件拷贝到该文件夹下即可

    

3,编译

1)直接输入“g++ -o Threadpool main.cpp”,报错

    报了好几屏错误,看开头部分,应该是没有选择c++11支持。

2)添加c++11支持,“g++ -o Threadpool -std= c++11 main.cpp”,仍有错误

    通过关键词“undefined reference to 'pthread_create'”去google搜索,可知:

pthread不是Linux下的默认的库,也就是在链接的时候,无法找到phread库中该函数的入口地址,于是链接会失败。

需要添加“-pthread”编译选项。注意,老版本是添加“-lpthread”,这里要感谢http://blog.chinaunix.net/uid-25909722-id-3026989.html,刚开始我一直添加“-lpthread”,并不能解决该编译错误

3)添加“-pthread”编译选项,编译成功,运行如下图:

你可能感兴趣的文章
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka生产者---大数据之Nifi工作笔记0036
查看>>
NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
查看>>
NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
查看>>
NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
查看>>
NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
查看>>
NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
查看>>
NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
查看>>
NIFI大数据进阶_实时同步MySql的数据到Hive中去_可增量同步_实时监控MySql数据库变化_操作方法说明_01---大数据之Nifi工作笔记0033
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_01_实际操作---大数据之Nifi工作笔记0029
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
查看>>
NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
查看>>
NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
查看>>
NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
查看>>
NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南002---大数据之Nifi工作笔记0069
查看>>
NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
查看>>
NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
查看>>
NIH发布包含10600张CT图像数据库 为AI算法测试铺路
查看>>
Nim教程【十二】
查看>>
Nim游戏
查看>>
NIO ByteBuffer实现原理
查看>>