IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 线程池 + 消息队列 代码实现 -> 正文阅读

[C++知识库]C++ 线程池 + 消息队列 代码实现

作者:recommend-item-box-tow

1. 消息队列- ConcurrentQueue

在这里插入图片描述
在这里插入图片描述

消息队列用一个类:ConcurrentQueue进行封装,拥有成员**_queue**,来存放元素;内部实现pushpop函数,来对队列进行入队和出队操作。

message_queue.h


#ifndef NET_FRAME_CONCURRENT_QUEUE_H
#define NET_FRAME_CONCURRENT_QUEUE_H
 
#include <queue>
#include <mutex>
#include <condition_variable>

template<class Type>
/*消息队列实现*/
class ConcurrentQueue {
    ConcurrentQueue& operator=(const ConcurrentQueue&) = delete;

    ConcurrentQueue(const ConcurrentQueue& other) = delete;

public:
    ConcurrentQueue() : _queue(), _mutex(), _condition() { }

    virtual ~ConcurrentQueue() { }

    void Push(Type record) {
        std::lock_guard <std::mutex> lock(_mutex);
        _queue.push(record);
        //每增加一个元素,用条件变量进行通知。
        _condition.notify_one();
    }

    bool Pop(Type& record, bool isBlocked = true) {
        if (isBlocked) {
            std::unique_lock <std::mutex> lock(_mutex);
            //当队列为空就进行wait阻塞等待。
            while (_queue.empty()) {
                _condition.wait(lock);
            }
        }
        else // If user wants to retrieve data in non-blocking mode
        {
            std::lock_guard <std::mutex> lock(_mutex);
            if (_queue.empty()) {
                return false;
            }
        }

        record = std::move(_queue.front());
        _queue.pop();
        return true;
    }

    int32_t Size() {
        std::lock_guard <std::mutex> lock(_mutex);
        return _queue.size();
    }

    bool Empty() {
        std::lock_guard <std::mutex> lock(_mutex);
        return _queue.empty();
    }

private:
    std::queue <Type> _queue;
    mutable std::mutex _mutex;
    std::condition_variable _condition;
};
 
 
#endif //NET_FRAME_CONCURRENT_QUEUE_H

2. 线程池-ThreadPool

封装了ThreadPool类,该类需要指定线程的数量_threads,包含用来存放线程的_workers容器。
在创建线程的时候,需要指定线程的处理函数lambda表达式以及元素的处理函数_handler:将消息队列的元素取出,然后作为_handler函数的形参进行处理。

在这里插入图片描述

Submit方法用于往消息队列里增加元素。

在这里插入图片描述
thread_pool.h

#ifndef NET_FRAME_THREAD_POOL_H
#define NET_FRAME_THREAD_POOL_H
 
#include "message_queue.h"
 
#include <vector>
#include <queue>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>
#include <stdexcept>
 
#define MIN_THREADS 10
 
 
template<class Type>
class ThreadPool {
    ThreadPool& operator=(const ThreadPool&) = delete;

    ThreadPool(const ThreadPool& other) = delete;

public:
    ThreadPool(int32_t threads, std::function<void(Type& record)> handler);

    virtual ~ThreadPool();

    void Submit(Type record);

private:

private:
    bool _shutdown;
    int32_t _threads;
    std::function<void(Type& record)> _handler;
    std::vector <std::thread> _workers;
    ConcurrentQueue <Type> _tasks;
};

template<class Type>
ThreadPool<Type>::ThreadPool(int32_t threads, std::function<void(Type &record)> handler)
        : _shutdown(false),
            _threads(threads),
            _handler(handler),
            _workers(),
            _tasks() {
    if (_threads < MIN_THREADS)
        _threads = MIN_THREADS;


    for (int32_t i = 0; i < _threads; ++i)
        _workers.emplace_back(
                [this] {
                    while (!_shutdown) {
                        Type record;
                        this->_tasks.Pop(record, true);
                        this->_handler(record);
                    }
                }
        );
}


template<class Type>
ThreadPool<Type>::~ThreadPool() {
    for (std::thread &worker: _workers)
        worker.join();
}


template<class Type>
void ThreadPool<Type>::Submit(Type record) {
    _tasks.Push(record);
}
 
 
 
 
#endif //NET_FRAME_THREAD_POOL_H

3. 测试代码

#include"message_queue.h"
#include"thread_pool.h"
#include<iostream>

std::mutex mutex_;

void threadProcess(int value){
    std::unique_lock<std::mutex> lock_(mutex_);
    std::cout<<"current threadId:"<<std::this_thread::get_id()<<" value:"<<value<<std::endl;
}
int main(){
    std::cout<<"main threadId:"<<std::this_thread::get_id()<<std::endl;
    ThreadPool<int> threadPool(15,threadProcess);
    for(int i=0;i<100000;++i){
        threadPool.Submit(i);
    }
    return 0;
}

4.运行截图

在这里插入图片描述

ps-ef |grep main
在这里插入图片描述
top -H -p 23796
可以看出有16个进程正在运行。

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-08 07:51:17  更:2022-05-08 07:53:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 21:56:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码