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

相关文章

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Java Instrumentation从概念到基本用法详解

《JavaInstrumentation从概念到基本用法详解》JavaInstrumentation是java.lang.instrument包提供的API,允许开发者在类被JVM加载时对其进行修改... 目录一、什么是 Java Instrumentation主要用途二、核心概念1. Java Agent

Kotlin 协程之Channel的概念和基本使用详解

《Kotlin协程之Channel的概念和基本使用详解》文章介绍协程在复杂场景中使用Channel进行数据传递与控制,涵盖创建参数、缓冲策略、操作方式及异常处理,适用于持续数据流、多协程协作等,需注... 目录前言launch / async 适合的场景Channel 的概念和基本使用概念Channel 的

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

一文带你迅速搞懂路由器/交换机/光猫三者概念区别

《一文带你迅速搞懂路由器/交换机/光猫三者概念区别》讨论网络设备时,常提及路由器、交换机及光猫等词汇,日常生活、工作中,这些设备至关重要,居家上网、企业内部沟通乃至互联网冲浪皆无法脱离其影响力,本文将... 当谈论网络设备时,我们常常会听到路由器、交换机和光猫这几个名词。它们是构建现代网络基础设施的关键组成

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

MySQL 事务的概念及ACID属性和使用详解

《MySQL事务的概念及ACID属性和使用详解》MySQL通过多线程实现存储工作,因此在并发访问场景中,事务确保了数据操作的一致性和可靠性,下面通过本文给大家介绍MySQL事务的概念及ACID属性和... 目录一、什么是事务二、事务的属性及使用2.1 事务的 ACID 属性2.2 为什么存在事务2.3 事务

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

【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)