基于任务组的线程池(SequentialThreadPool)

avatar
作者
猴君
阅读量:0

背景

考虑有多个任务,比如有5个数据采集设备,需要对每个设备采集的数据进行处理,单个设备的数据需要按照数据产生的顺序进行处理,每个设备产生的频率不一致。应该如何处理上述需求?

  • 方案一:
    多线程处理:对每个设备采用一个线程进行处理,确保了设备的数据顺序。
    弊端:当设备增加时,浪费了大量线程;对于频率低的设备线程利用率低,对于频率高的设备处理能力可能不足。
  • 方案二:
    线程池处理:虽然能很好的利用资源,但无法保证单个设备的数据有序性。
  • 方案三:
    协程:协程能较好的处理此问题,但需要C++20支持,且无栈协程具有传染性。

基于上述情况,提出了一种按照任务组进行顺序执行的线程池。

简介

基于C++11实现的一个head-only的线程池。其区别于普通线程池在于:可以对任务进行分组,同一个组内的任务按照入队顺序进行执行,不同组之间的任务抢占式执行。线程资源平衡利用,避免出现某个线程利用率高,某个线程利用率低的问题。

源码

由于源码可能会更新,故参见Github: SequentialThreadPool

使用

#include "SequentialThreadPool.hpp" #include <iostream> #include <sstream>  int main() {     const auto start = std::chrono::high_resolution_clock::now();      SequentialThreadPool pool(4);     for (int task = 0; task < 30; ++task) {         const int group = task % 5; // Task Grouping         pool.enqueue(group, [=]() {             const auto end = std::chrono::high_resolution_clock::now();             const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();             const int sleep = task == 0 ? 200 : rand() % 100 + 50;             std::stringstream ss;             ss << "Time:" << duration << ", group:" << group << ", task:" << task                << ", tid:" << std::this_thread::get_id() << ", sleep:" << sleep << "ms\n";             std::cout << ss.str();             std::this_thread::sleep_for(std::chrono::milliseconds(sleep));         });     }      return 0; } 

输出

Time:5,   group:0, task:0,  tid:23788, sleep:200ms Time:5,   group:1, task:1,  tid:26944, sleep:91ms Time:5,   group:2, task:2,  tid:27324, sleep:91ms Time:5,   group:3, task:3,  tid:21836, sleep:91ms Time:105, group:4, task:4,  tid:27324, sleep:117ms Time:105, group:3, task:8,  tid:26944, sleep:117ms Time:105, group:2, task:7,  tid:21836, sleep:117ms Time:216, group:1, task:6,  tid:23788, sleep:91ms Time:231, group:0, task:5,  tid:27324, sleep:84ms Time:231, group:3, task:13, tid:26944, sleep:84ms Time:231, group:2, task:12, tid:21836, sleep:84ms Time:324, group:4, task:9,  tid:21836, sleep:50ms Time:324, group:2, task:17, tid:23788, sleep:117ms Time:324, group:1, task:11, tid:27324, sleep:50ms Time:324, group:0, task:10, tid:26944, sleep:50ms Time:386, group:0, task:15, tid:27324, sleep:119ms Time:386, group:4, task:14, tid:21836, sleep:119ms Time:386, group:3, task:18, tid:26944, sleep:119ms Time:449, group:1, task:16, tid:23788, sleep:84ms Time:513, group:0, task:20, tid:26944, sleep:74ms Time:513, group:3, task:23, tid:21836, sleep:74ms Time:513, group:2, task:22, tid:27324, sleep:74ms Time:543, group:4, task:19, tid:23788, sleep:50ms Time:589, group:1, task:21, tid:21836, sleep:128ms Time:589, group:3, task:28, tid:27324, sleep:128ms Time:589, group:2, task:27, tid:26944, sleep:128ms Time:605, group:0, task:25, tid:23788, sleep:119ms Time:728, group:1, task:26, tid:23788, sleep:74ms Time:728, group:4, task:24, tid:21836, sleep:108ms Time:838, group:4, task:29, tid:21836, sleep:112ms 

任务执行顺序图

基于上述执行进行进行图形化后如下,组内任务顺序执行,组间任务并行执行。
在这里插入图片描述

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!