C++可扩展性与多线程超详细精讲

 更新时间:2022年10月31日 11:00:03   作者:无水先生  
这篇文章主要介绍了C++可扩展性与多线程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

一、可扩展性和多线程

基于 Boost.Asio 之类的库开发程序与通常的 C++ 风格不同。可能需要更长时间才能返回的函数不再按顺序调用。 Boost.Asio 不调用阻塞函数,而是启动异步操作。操作完成后应该调用的函数现在在相应的处理程序中调用。这种方法的缺点是顺序执行函数的物理分离,这会使代码更难理解。

诸如 Boost.Asio 之类的库通常用于实现更高的效率。无需等待操作完成,程序可以在其间执行其他任务。因此,可以启动多个同时执行的异步操作——请记住,异步操作通常用于访问进程之外的资源。由于这些资源可以是不同的设备,它们可以独立工作并同时执行操作。

可扩展性描述了程序有效地从额外资源中受益的能力。借助 Boost.Asio,可以从外部设备同时执行操作的能力中受益。如果使用线程,则可以在可用的 CPU 内核上同时执行多个功能。 Boost.Asio 的线程提高了可伸缩性,因为您的程序可以利用内部和外部设备,这些设备可以独立执行操作或相互协作执行操作。

如果在 boost::asio::io_service 类型的对象上调用成员函数 run(),则在同一线程中调用关联的处理程序。通过使用多个线程,程序可以多次调用 run()。一旦异步操作完成,I/O 服务对象将在这些线程之一中执行处理程序。如果第二个操作在第一个操作之后不久完成,则 I/O 服务对象可以在不同的线程中执行处理程序。现在,不仅进程外的操作可以并发执行,进程内的处理程序也可以并发执行。

二、线程示例

示例 32.3。 I/O 服务对象的两个线程同时执行处理程序

#include <boost/asio/io_service.hpp>
#include <boost/asio/steady_timer.hpp>
#include <chrono>
#include <thread>
#include <iostream>
using namespace boost::asio;
int main()
{
  io_service ioservice;
  steady_timer timer1{ioservice, std::chrono::seconds{3}};
  timer1.async_wait([](const boost::system::error_code &ec)
    { std::cout << "3 sec\n"; });
  steady_timer timer2{ioservice, std::chrono::seconds{3}};
  timer2.async_wait([](const boost::system::error_code &ec)
    { std::cout << "3 sec\n"; });
  std::thread thread1{[&ioservice](){ ioservice.run(); }};
  std::thread thread2{[&ioservice](){ ioservice.run(); }};
  thread1.join();
  thread2.join();
}

前面的示例已在示例 32.3 中转换为多线程程序。使用 std::thread,在 main() 中创建了两个线程。在每个线程中的唯一 I/O 服务对象上调用 run()。这使得 I/O 服务对象可以在异步操作完成时使用两个线程来执行处理程序。

在示例 32.3 中,两个闹钟都应在三秒后响起。因为有两个线程可用,所以两个 lambda 函数可以同时执行。如果在执行第一个闹钟的处理程序时第二个闹钟响起,则可以在第二个线程中执行该处理程序。如果第一个闹钟的handler已经返回,I/O服务对象可以使用任意线程执行第二个handler。

当然,使用线程并不总是有意义的。示例 32.3 可能不会将消息按顺序写入标准输出流。相反,它们可能会混淆。两个处理程序可能同时在两个线程中运行,共享全局资源 std::cout。为避免中断,需要同步对 std::cout 的访问。如果处理程序不能同时执行,线程的优势就丧失了。

示例 32.4。两个 I/O 服务对象各有一个线程并发执行处理程序

#include <boost/asio/io_service.hpp>
#include <boost/asio/steady_timer.hpp>
#include <chrono>
#include <thread>
#include <iostream>
using namespace boost::asio;
int main()
{
  io_service ioservice1;
  io_service ioservice2;
  steady_timer timer1{ioservice1, std::chrono::seconds{3}};
  timer1.async_wait([](const boost::system::error_code &ec)
    { std::cout << "3 sec\n"; });
  steady_timer timer2{ioservice2, std::chrono::seconds{3}};
  timer2.async_wait([](const boost::system::error_code &ec)
    { std::cout << "3 sec\n"; });
  std::thread thread1{[&ioservice1](){ ioservice1.run(); }};
  std::thread thread2{[&ioservice2](){ ioservice2.run(); }};
  thread1.join();
  thread2.join();
}

对单个 I/O 服务对象重复调用 run() 是使基于 Boost.Asio 的程序更具可扩展性的推荐方法。但是,您也可以创建多个 I/O 服务对象,而不是为一个 I/O 服务对象提供多个线程。

在示例 32.4 中,两个 I/O 服务对象在两个类型为 boost::asio::steady_timer 的闹钟旁边使用。该程序基于两个线程,每个线程绑定到另一个 I/O 服务对象。两个 I/O 对象 timer1 和 timer2 不再绑定到同一个 I/O 服务对象。它们绑定到不同的对象。

示例 32.4 的工作方式与之前相同。无法就何时使用多个 I/O 服务对象提供一般性建议。因为 boost::asio::io_service 代表一个操作系统接口,所以任何决定都取决于特定的接口。

在 Windows 上,boost::asio::io_service 通常基于 IOCP,在 Linux 上,它基于 epoll()。拥有多个 I/O 服务对象意味着将使用多个 I/O 完成端口,或者将多次调用 epoll()。这是否比仅使用一个 I/O 完成端口或一次调用 epoll() 更好取决于具体情况。

到此这篇关于C++可扩展性与多线程超详细精讲的文章就介绍到这了,更多相关C++可扩展性与多线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++中std::stringstream多类型数据拼接和提取用法小结

    C++中std::stringstream多类型数据拼接和提取用法小结

    本文主要介绍了C++中std::stringstream多类型数据拼接和提取用法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-09-09
  • C++ std::map几种遍历方式(正序倒序)

    C++ std::map几种遍历方式(正序倒序)

    这篇文章主要介绍了C++ std::map几种遍历方式,包含正序遍历和倒序遍历,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-02-02
  • 在C++中反射调用.NET的方法(一)

    在C++中反射调用.NET的方法(一)

    为什么要在C++中调用.NET呢?接下来通过本文给大家介绍在C++中反射调用.NET的方法(一),需要的朋友参考下吧
    2017-02-02
  • C语言实现经典24点算法

    C语言实现经典24点算法

    这篇文章主要为大家详细介绍了C语言实现经典24点算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • C++中main函数怎样调用类内函数

    C++中main函数怎样调用类内函数

    这篇文章主要介绍了C++中main函数怎样调用类内函数问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Matlab实现简单扩频语音水印算法详解

    Matlab实现简单扩频语音水印算法详解

    本文主要介绍了通过MATLAB设计并实现一种基于音频的扩频水印算法,从而了解参数对扩频水印算法性能的影响。代码具有一定的价值,感兴趣的小伙伴可以关注一下
    2021-11-11
  • c语言实现的货物管理系统实例代码(增加删除 查找货物信息等功能)

    c语言实现的货物管理系统实例代码(增加删除 查找货物信息等功能)

    这篇文章主要介绍了c语言实现的货物管理系统,可增加删除、查找货物信息、显示货物信息、排序货物销量等操作,大家参考使用吧
    2013-11-11
  • C++中的编译与链接

    C++中的编译与链接

    这篇文章主要介绍了C++中的编译与链接,编译型语言SHI c++最大的优点,相比于Python这种解释型语言,C++在编译阶段就进行了许多处理,在执行阶段便具有高效性,下面我们就来详细讲解该内容吧
    2021-12-12
  • C/C++格式化日志库实现代码

    C/C++格式化日志库实现代码

    这篇文章主要介绍了C/C++格式化日志库实现代码,需要的朋友可以参考下
    2019-04-04
  • C语言详细讲解通过递归实现扫雷的展开

    C语言详细讲解通过递归实现扫雷的展开

    windows自带的游戏《扫雷》是陪伴了无数人的经典游戏,本文将利用C语言实现这一经典的游戏,文中的示例代码讲解详细,感兴趣的可以学习一下
    2022-05-05

最新评论