Boost库一些概念

2024-09-07 12:44
文章标签 概念 boost

本文主要是介绍Boost库一些概念,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Boost库一些概念

回调函数和异步操作的设计优势

在 Boost.Asio 中,异步操作和回调函数的设计有以下几个主要优势:1. 非阻塞 I/O非阻塞: 异步操作不会阻塞线程,允许程序在等待 I/O 操作完成的同时执行其他任务。这提高了程序的响应性和并发处理能力。事件驱动: 通过事件循环和回调函数,程序可以以事件驱动的方式处理 I/O 操作,避免了传统阻塞 I/O 模型中的线程阻塞问题。2. 高效利用线程资源线程池: io_context 可以与线程池结合使用,多个线程可以并行执行异步操作的回调函数,从而提高并发处理能力。避免线程浪费: 在阻塞 I/O 模型中,每个 I/O 操作都需要一个独立的线程,这会导致线程资源的浪费。异步 I/O 模型通过回调函数和事件循环,避免了线程的浪费。3. 简化并发编程简化并发控制: 异步操作和回调函数的设计简化了并发编程的复杂性。开发者不需要手动管理线程同步和锁机制,只需关注异步操作的调度和回调函数的实现。避免死锁和竞态条件: 通过事件循环和回调函数,可以避免传统多线程编程中常见的死锁和竞态条件问题。4. 灵活性和可扩展性灵活调度: 回调函数可以访问 io_context 对象,并继续调度新的异步操作。这种设计允许程序在处理一个异步操作的同时,调度其他异步操作,提高了程序的灵活性和可扩展性。模块化设计: 异步操作和回调函数的设计支持模块化编程,开发者可以将复杂的业务逻辑拆分为多个小的异步操作和回调函数,便于维护和扩展。5. 提高系统吞吐量高吞吐量: 通过非阻塞 I/O 和多线程并发处理,异步操作和回调函数的设计可以显著提高系统的吞吐量。特别是在高并发场景下,异步 I/O 模型比阻塞 I/O 模型更具优势。资源利用率: 异步操作和回调函数的设计可以更高效地利用系统资源,如 CPU 和内存,从而提高系统的整体性能。

关于io_context

 // 创建一个 io_context 对象,用于管理异步 I/O 操作net::io_context ioc{1};//传值1表示线程数 建议线程数不要超过 CPU 核心数的两倍* io_context 是 Boost.Asio 库中的核心类之一,用于管理异步 I/O 操作的调度。它提供了事件循环和任务队列,用于处理异步操作的回调。*     事件循环: io_context 维护一个事件循环,用于处理异步操作的回调。事件循环会不断地检查是否有异步操作完成,并调用相应的回调函数。*     任务队列: io_context 内部维护一个任务队列,用于存储待执行的异步操作和回调函数。任务队列中的任务会在事件循环中依次执行。*    线程池: io_context 可以与线程池结合使用,以提高并发处理能力。通过指定线程数,io_context 可以在多个线程上并行执行任务。!  构造函数: io_context 的构造函数可以接受一个整数参数,表示线程池中的线程数。如果不指定参数,默认使用单线程。! 异步操作: io_context 支持多种异步操作,如 async_accept、async_read、async_write 等。异步操作不会阻塞线程,而是在操作完成后调用回调函数。
! 回调函数: 异步操作的回调函数会在事件循环中执行。回调函数可以访问 io_context 对象,并继续调度新的异步操作。
! 线程安全: io_context 对象本身是线程安全的,可以在多个线程中调用 run 方法。但是,异步操作的回调函数通常在一个线程中执行,因此需要注意线程同步问题。
! 线程池: 通过使用线程池,可以提高并发处理能力。多个线程可以并行执行异步操作的回调函数,从而提高程序的吞吐量

net::io_context ioc{4}; 的线程管理

在 Boost.Asio 中,net::io_context ioc{4};
并不会自动创建一个线程池。

它只是创建了一个 io_context 对象,并指定了线程池中的线程数为 4。

要实现线程池,需要手动创建多个线程,
并在每个线程中调用 ioc.run() 方法。

  1. io_context 的线程数

    io_context 的线程数: net::io_context ioc{4}; 指定了 io_context 对象的并发处理能力为 4 个线程。这意味着 io_context 可以并行处理最多 4 个异步操作的回调。
    线程池: 这并不意味着自动创建了一个线程池。线程池需要手动创建和管理。

  2. 手动创建线程池

手动创建线程池: 需要手动创建多个线程,并在每个线程中调用 ioc.run() 方法。这样可以实现线程池,提高并发处理能力。

#include <boost/asio.hpp>
#include <iostream>
#include <thread>namespace net = boost::asio;int main() {try {// 创建 io_context 对象,使用 4 个线程net::io_context ioc{4};// 输出服务器信息std::cout << "Server started" << std::endl;// 使用 signal_set 处理 SIGINT 和 SIGTERM 信号net::signal_set signals(ioc, SIGINT, SIGTERM);signals.async_wait([&ioc](boost::system::error_code const& error, int signal_number) {if (error) {std::cerr << "Error: " << error.message() << std::endl;return;}std::cout << "Signal " << signal_number << " received." << std::endl;ioc.stop();});// 创建并启动服务器std::make_shared<CServer>(ioc, 8080)->Start();// 创建多个线程,每个线程调用 ioc.run()std::vector<std::thread> threads;for (int i = 0; i < 4; ++i) {threads.emplace_back([&ioc]() {ioc.run();});}// 等待所有线程完成for (auto& t : threads) {t.join();}} catch (std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;return 1;}
}

关于io_context 的状态


io_context 的状态主要包括以下几种:1. 运行状态
run(): 调用 run() 方法后,io_context 进入运行状态,开始处理异步操作的回调。run() 方法会阻塞当前线程,直到所有异步操作完成或 io_context 被停止。
run_one(): 调用 run_one() 方法后,io_context 会处理一个异步操作的回调,然后返回。run_one() 方法不会阻塞线程,适合在需要处理单个异步操作的场景中使用。
poll(): 调用 poll() 方法后,io_context 会处理所有当前可用的异步操作的回调,然后返回。poll() 方法不会阻塞线程,适合在需要非阻塞处理异步操作的场景中使用。
poll_one(): 调用 poll_one() 方法后,io_context 会处理一个当前可用的异步操作的回调,然后返回。poll_one() 方法不会阻塞线程,适合在需要处理单个异步操作的场景中使用。
2. 停止状态
stop(): 调用 stop() 方法后,io_context 进入停止状态。stop() 方法会使 run()、run_one()、poll() 和 poll_one() 方法返回,不再处理新的异步操作。
stopped(): 调用 stopped() 方法可以检查 io_context 是否处于停止状态。如果 io_context 处于停止状态,stopped() 方法返回 true,否则返回 false。
3. 重启状态
restart(): 调用 restart() 方法后,io_context 会重置其状态,使其可以再次调用 run()、run_one()、poll() 和 poll_one() 方法。restart() 方法通常在 stop() 方法之后调用,以重新启动 io_context。
#include <boost/asio.hpp>
#include <iostream>
#include <thread>namespace net = boost::asio;int main() {try {// 创建 io_context 对象net::io_context ioc;// 输出服务器信息std::cout << "Server started" << std::endl;// 使用 signal_set 处理 SIGINT 和 SIGTERM 信号net::signal_set signals(ioc, SIGINT, SIGTERM);signals.async_wait([&ioc](boost::system::error_code const& error, int signal_number) {if (error) {std::cerr << "Error: " << error.message() << std::endl;return;}std::cout << "Signal " << signal_number << " received." << std::endl;ioc.stop();});// 创建并启动服务器std::make_shared<CServer>(ioc, 8080)->Start();// 运行 io_context,处理所有的异步事件ioc.run();// 检查 io_context 是否处于停止状态if (ioc.stopped()) {std::cout << "io_context is stopped." << std::endl;}// 重启 io_contextioc.restart();// 再次运行 io_contextioc.run();} catch (std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;return 1;}
}

关于run() 方法

ioc.run() 的运行次数在 Boost.Asio 中,io_context::run() 方法用于启动事件循环,处理异步操作的回调。1. 单次运行单次运行: 通常情况下,ioc.run() 只需要运行一次。run() 方法会阻塞当前线程,直到所有异步操作完成或 io_context 被停止。
事件循环: run() 方法启动事件循环,不断检查是否有异步操作完成,并调用相应的回调函数。事件循环会一直运行,直到没有更多的异步操作需要处理。
2. 多次运行多次运行: 在某些情况下,可能需要多次调用 run() 方法。例如,如果 io_context 对象在多个线程中使用,每个线程都可以调用 run() 方法,以提高并发处理能力。
线程池: 通过在多个线程中调用 run() 方法,可以创建一个线程池,提高异步操作的并发处理能力。每个线程都会参与事件循环的处理,从而提高系统的吞吐量。
3. 停止和重启停止: 可以通过调用 ioc.stop() 方法停止事件循环。stop() 方法会使 run() 方法返回,不再处理新的异步操作。
重启: 如果需要重新启动事件循环,可以调用 ioc.restart() 方法。restart() 方法会重置 io_context 的状态,使其可以再次调用 run() 方法。

关于使用线程池 多个线程可以共享同一个 io_context 对象

使用线程池的 io_context
在 Boost.Asio 中,可以通过创建多个线程并在线程中调用 io_context::run() 方法来实现线程池。这样可以提高并发处理能力,充分利用多核 CPU 的性能。

namespace net = boost::asio;int main() {try {// 创建 io_context 对象net::io_context ioc;// 输出服务器信息std::cout << "Server started" << std::endl;// 使用 signal_set 处理 SIGINT 和 SIGTERM 信号net::signal_set signals(ioc, SIGINT, SIGTERM);signals.async_wait([&ioc](boost::system::error_code const& error, int signal_number) {if (error) {std::cerr << "Error: " << error.message() << std::endl;return;}std::cout << "Signal " << signal_number << " received." << std::endl;ioc.stop();});// 创建并启动服务器std::make_shared<CServer>(ioc, 8080)->Start();// 创建线程池const int num_threads = 4; // 线程池中的线程数std::vector<std::thread> threads;// 启动线程池中的线程,每个线程调用 ioc.run()for (int i = 0; i < num_threads; ++i) {threads.emplace_back([&ioc]() {ioc.run();});}// 等待所有线程完成for (auto& t : threads) {t.join();}} catch (std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;return 1;}
}

底层实现

Boost.Asio 的底层实现依赖于不同操作系统的原生 I/O 多路复用机制,包括但不限于 epoll、kqueue、IOCP 和 select。通过使用这些高效的 I/O 机制,Boost.Asio 提供了统一的接口来处理异步 I/O 操作,适用于各种操作系统和场景。

Linux: 使用 epoll。
BSD: 使用 kqueue。
Windows: 使用 IOCP。
通用平台: 使用 select。

1. Linux 平台

   epoll: 在 Linux 平台上,Boost.Asio 使用 epoll 作为底层的 I/O 多路复用机制。epoll 是 Linux 特有的高效 I/O 事件通知机制,适用于高并发场景。epoll 的优势:高效的事件通知: epoll 使用事件驱动的方式,避免了 select 和 poll 的轮询开销。支持大规模并发连接: epoll 可以处理大量并发连接,适用于高并发服务器。

2. BSD 平台

   kqueue: 在 BSD 平台上(如 FreeBSD、macOS),Boost.Asio 使用 kqueue 作为底层的 I/O 多路复用机制。kqueue 是 BSD 特有的高效 I/O 事件通知机制。kqueue 的优势:高效的事件通知: kqueue 使用事件驱动的方式,避免了 select 和 poll 的轮询开销。支持多种事件类型: kqueue 不仅支持 I/O 事件,还支持信号、定时器等多种事件类型。

3. Windows 平台

   IOCP (I/O Completion Ports): 在 Windows 平台上,Boost.Asio 使用 IOCP 作为底层的异步 I/O 机制。IOCP 是 Windows 特有的高效异步 I/O 机制,适用于高并发服务器。IOCP 的优势:高效的异步 I/O: IOCP 提供了高效的异步 I/O 操作,避免了线程阻塞。支持大规模并发连接: IOCP 可以处理大量并发连接,适用于高并发服务器。

4. 通用平台

   select: 在其他平台上,Boost.Asio 使用 select 作为底层的 I/O 多路复用机制。select 是一种通用的 I/O 多路复用机制,适用于各种操作系统。select 的优势:跨平台支持: select 是一种通用的 I/O 多路复用机制,适用于各种操作系统。简单易用: select 的接口简单易用,适合处理少量并发连接。

这篇关于Boost库一些概念的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1145092

相关文章

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

【MRI基础】TR 和 TE 时间概念

重复时间 (TR) 磁共振成像 (MRI) 中的 TR(重复时间,repetition time)是施加于同一切片的连续脉冲序列之间的时间间隔。具体而言,TR 是施加一个 RF(射频)脉冲与施加下一个 RF 脉冲之间的持续时间。TR 以毫秒 (ms) 为单位,主要控制后续脉冲之前的纵向弛豫程度(T1 弛豫),使其成为显著影响 MRI 中的图像对比度和信号特性的重要参数。 回声时间 (TE)

计算机网络基础概念 交换机、路由器、网关、TBOX

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、VLAN是什么?二 、交换机三、路由器四、网关五、TBOXTelematics BOX,简称车载T-BOX,车联网系统包含四部分,主机、车载T-BOX、手机APP及后台系统。主机主要用于车内的影音娱乐,以及车辆信息显示;车载T-BOX主要用于和后台系统/手机APP通信,实现手机APP的车辆信息显示与控

01 Docker概念和部署

目录 1.1 Docker 概述 1.1.1 Docker 的优势 1.1.2 镜像 1.1.3 容器 1.1.4 仓库 1.2 安装 Docker 1.2.1 配置和安装依赖环境 1.3镜像操作 1.3.1 搜索镜像 1.3.2 获取镜像 1.3.3 查看镜像 1.3.4 给镜像重命名 1.3.5 存储,载入镜像和删除镜像 1.4 Doecker容器操作 1.4

【机器学习-一-基础概念篇】

机器学习 定义分类算法 应用 定义 机器学习最早是被Arthur Samuel 提出的一个概念,指计算机无需明确编程即可学习的研究领域。1950年他发明的跳棋程序,这个人机对弈游戏让他的声名鹊起,机器学习这个概念才进入大众的是视线。 在这个跳棋程序里,他编程了一种算法,这个程序与Arthur下了数万次跳棋,计算机逐渐学会了下在哪里有更大的可能会赢得比赛,哪里会输,通过这种方法,最

【吊打面试官系列-Redis面试题】说说 Redis 哈希槽的概念?

大家好,我是锋哥。今天分享关于 【说说 Redis 哈希槽的概念?】面试题,希望对大家有帮助; 说说 Redis 哈希槽的概念? Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽, 集群的每个节点负责一部分 hash 槽。

AI辅助编程里的 Atom Group 的概念和使用

背景 在我们实际的开发当中,一个需求往往会涉及到多个文件修改,而需求也往往有相似性。 举个例子,我经常需要在 auto-coder中需要添加命令行参数,通常是这样的: /coding 添加一个新的命令行参数 --chat_model 默认值为空 实际上这个需求涉及到以下文件列表: /Users/allwefantasy/projects/auto-coder/src/autocoder/auto

读软件设计的要素04概念的关系

1. 概念的关系 1.1. 概念是独立的,彼此间无须相互依赖 1.1.1. 一个概念是应该独立地被理解、设计和实现的 1.1.2. 独立性是概念的简单性和可重用性的关键 1.2. 软件存在依赖性 1.2.1. 不是说一个概念需要依赖另一个概念才能正确运行 1.2.2. 只有当一个概念存在时,包含另一个概念才有意义 1.3. 概念依赖关系图简要概括了软件的概念和概念存在的理

Boost程序库入门学习

优秀的程序员要能够知其所以然,而不是重复的造轮子,近期目标是学习优秀的第三方库,同时尝试使用C++11/14新特性,然后吸取精华用到项目中去,加油~ 参考书籍: 罗剑锋写的《Boost程序库完全开发指南》和《Boost程序库探秘》,前者是一个大体的介绍,后者是针对一些诸如模板元编程等高级特性做了深入的探讨。 一、Boost库概述 Boost是一个功能强大、构造精巧、跨平台、开源并且完全

【生物信息学算法】图算法1:概念和算法

文章目录 1. 图的定义、分类、表达方式图的定义图的分类表达方式Python实现 2.相邻节点和度概念定义python实现 3.路径、距离和搜索路径和距离搜索环 4.图论中的欧拉定理 1. 图的定义、分类、表达方式 图的定义 图G可以由两个集合来定义,即G=(V,E)。其中,V是对象的集合,称为图的顶点或节点; E是V中(u,v)顶点对的集合,称为边或弧,表示u和v之间的关系