C++Helper--使用C++11实现半同步半异步线程池,接口接受:函数对象、成员函数、普通函数、fucntion和lamda表达式等。

  本文使用C++11的线程、互斥量和条件变量,实现了一个轻巧的线程池,可用于大量并发任务的场景,以避免频繁的线程创建和销毁,节约系统资源。

  本文对处理任务的接口,也进行了包装,可接受:函数对象、成员函数、普通函数、fucntion和lamda表达式,便于完美的应用到实际工作中。

  本文源码见【完整代码】章节,或GitHub:https://github.com/deargo/cpphelper。

线程池介绍

  在处理大量并发任务的时候,如果按照传统的方式,一个请求一个线程来处理请求任务,大量的线程创建和销毁,将消耗过多的系统资源,还增加了线程上下文切换的开销,而通过线程池技术,就可以很好的解决这些问题。

  线程池技术通过在系统中预先创建一定数量的线程,当任务请求到来时从线程池中,分配一个预先创建的线程去处理任务,线程在完成任务之后,还可以重用,不会销毁,而是等待下次任务的到来。

  线程池分为半同步半异步线程池和领导者追随者线程池,本文将介绍的是前者。半同步半异步线程池分为三层:

  • 同步服务层:它处理来自上层的任务请求,上层的请求可能是并发的,这些请求不是马上就会被处理的,而是将这些任务放到一个同步排队层中,等待处理。
  • 同步排队层:来自上层的任务请求,都会加到排队层中,等待处理。
  • 异步服务层:这一层中会有多个线程,同时处理排队层中的任务,异步服务层从同步排队层中取出任务,并行的处理。

C++Helper--使用C++11实现半同步半异步线程池,接口接受:函数对象、成员函数、普通函数、fucntion和lamda表达式等。_第1张图片

关键技术分析

  通过上一节我们知道,排队层居于核心地位,因为上层会将任务添加到排队层中,下层同时也会取出任务,这里有一个同步的过程。

  在实现时,排队层就是一个同步队列,允许多个线程同时去添加,或取出任务,并且要保障操作过程是安全的。

  线程池有两个活动过程,一个是往同步队列中添加任务的过程,另一个是从同步队列中取出任务的过程。

C++Helper--使用C++11实现半同步半异步线程池,接口接受:函数对象、成员函数、普通函数、fucntion和lamda表达式等。_第2张图片

  线程池需启动一定数量的异步线程,来并行处理排队层中的任务,如果排队层中的任务为空,则需等待任务的到来,如果发现有新任务,则会唤醒一个线程来处理。

  同步服务层会不断的将新的任务,添加到同步排队层中。当任务非常多又耗时时,异步线程处理不过来,则会导致排队层任务过多,内存暴涨,因此需要添加上限,避免此问题。

  另外,对于任务类型,与线程池,本是不相关的,但考虑到实际运用,任务类型应支持:函数对象、成员函数、普通函数、fucntion和lamda表达式等,于是结合我的另外一篇博客《C++Helper--用C++11改进命令模式》,可对添加任务的接口,进行优化。

完整代码

#pragma once

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

#include 
#include 

你可能感兴趣的:(C++Helper系列,C/C++,c++,c++11,多线程,队列,并发编程)