C++异步数据交换实现方法介绍

 更新时间:2022年11月20日 09:13:22   作者:无水先生  
这篇文章主要介绍了C++异步数据交换实现方法,异步数据交换,除了阻塞函数 send() 和 recv() 之外,Boost.MPI 还支持与成员函数 isend() 和 irecv() 的异步数据交换

异步数据交换,除了阻塞函数 send() 和 recv() 之外,Boost.MPI 还支持与成员函数 isend() 和 irecv() 的异步数据交换。名称以 i 开头,表示函数立即返回。

示例 47.7。使用 irecv() 异步接收数据

#include <boost/mpi.hpp>
#include <boost/serialization/string.hpp>
#include <string>
#include <iostream>
int main(int argc, char *argv[])
{
  boost::mpi::environment env{argc, argv};
  boost::mpi::communicator world;
  if (world.rank() == 0)
  {
    std::string s;
    boost::mpi::request r = world.irecv(boost::mpi::any_source, 16, s);
    if (r.test())
      std::cout << s << '\n';
    else
      r.cancel();
  }
  else
  {
    std::string s = "Hello, world!";
    world.send(0, 16, s);
  }
}

Example47.7

示例 47.7 使用阻塞函数 send() 发送字符串“Hello, world!”但是,数据是通过异步函数 irecv() 接收的。此成员函数需要与 recv() 相同的参数。不同之处在于,当 irecv() 返回时,无法保证在 s 中已收到数据。

irecv() 返回类型为 boost::mpi::request 的对象。您可以调用 test() 来检查是否已收到数据。此成员函数返回一个布尔值。您可以根据需要随时调用 test()。因为 irecv() 是一个异步成员函数,所以第一次调用可能会返回 false,而第二次调用会返回 true。这意味着异步操作在两次调用之间完成。

示例 47.7 仅调用 test() 一次。如果在 s 中接收到数据,则将变量写入标准输出流。如果没有收到数据,则使用 cancel() 取消异步操作。

如果多次运行示例 47.7,有时会出现 Hello, world!显示,有时没有输出。结果取决于是否在调用 test() 之前接收到数据。

示例 47.8。使用 wait_all() 等待多个异步操作

#include <boost/mpi.hpp>
#include <boost/serialization/string.hpp>
#include <string>
#include <iostream>
int main(int argc, char *argv[])
{
  boost::mpi::environment env{argc, argv};
  boost::mpi::communicator world;
  if (world.rank() == 0)
  {
    boost::mpi::request requests[2];
    std::string s[2];
    requests[0] = world.irecv(1, 16, s[0]);
    requests[1] = world.irecv(2, 16, s[1]);
    boost::mpi::wait_all(requests, requests + 2);
    std::cout << s[0] << "; " << s[1] << '\n';
  }
  else if (world.rank() == 1)
  {
    std::string s = "Hello, world!";
    world.send(0, 16, s);
  }
  else if (world.rank() == 2)
  {
    std::string s = "Hello, moon!";
    world.send(0, 16, s);
  }
}

您可以多次调用 boost::mpi::request 上的 test() 来检测异步操作何时完成。但是,您也可以像示例 47.8 中那样调用阻塞函数 boost::mpi::wait_all()。 boost::mpi::wait_all() 是一个阻塞函数,但好处是可以等待多个异步操作完成。 boost::mpi::wait_all() 在它等待的所有异步操作都已完成时返回。

在示例 47.8 中,等级为 1 的进程发送“Hello, world!”以及排名 2 的过程“你好,月亮!”由于接收数据的顺序无关紧要,因此排名为 0 的进程调用 irecv()。由于程序只会在所有异步操作完成并接收到所有数据时生成输出,因此类型 boost::mpi::request 的返回值被传递给 boost::mpi::wait_all()。因为 boost::mpi::wait_all() 需要两个迭代器,所以 boost::mpi::request 类型的对象存储在一个数组中。开始和结束迭代器被传递给 boost::mpi::wait_all()

Boost.MPI 提供了额外的函数,您可以使用它们来等待异步操作的完成。 boost::mpi::wait_any() 在恰好一个异步操作完成时返回,boost::mpi::wait_some() 在至少一个异步操作完成时返回。这两个函数都返回一个 std::pair 指示哪个或哪些操作已完成。

boost::mpi::test_all()、boost::mpi::test_any() 和 boost::mpi::test_some() 通过一次调用测试多个异步操作的状态。这些函数是非阻塞的并立即返回。

到此这篇关于C++异步数据交换实现方法介绍的文章就介绍到这了,更多相关C++异步数据交换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • 详解C++中的const和constexpr

    详解C++中的const和constexpr

    这篇文章主要为大家介绍了C++中的const和constexpr ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • C++全密码生成的实现代码

    C++全密码生成的实现代码

    这篇文章主要为大家详细介绍了C++全密码生成的实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • C语言如何把浮点数转换为字符串

    C语言如何把浮点数转换为字符串

    这篇文章主要介绍了C语言如何把浮点数转换为字符串方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • C语言超全面讲解函数的使用方法上

    C语言超全面讲解函数的使用方法上

    函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数,由于篇幅过大,分为两篇讲解,下面开始上篇
    2022-04-04
  • C++深入讲解类与对象之OOP面向对象编程与封装

    C++深入讲解类与对象之OOP面向对象编程与封装

    学习过C语言的小伙伴知道:C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题,接下来让我们详细的了解
    2022-05-05
  • 详解QTreeWidget隐藏节点的两种方式

    详解QTreeWidget隐藏节点的两种方式

    本文主要介绍了QTreeWidget隐藏节点的两种方式,一种是直接隐藏,一种是间接隐藏,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • C++实现遗传算法

    C++实现遗传算法

    这篇文章主要介绍了C++实现遗传算法,以实例形式较为详细的分析了遗传算法的C++实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-12-12
  • C++解决合并两个排序的链表问题

    C++解决合并两个排序的链表问题

    本文主要介绍了通过C++解决合并两个排序的链表并使新链表中的节点仍然是递增排序的。文中代码讲解详细,有需要的朋友可以参考一下
    2021-12-12
  • C语言实现排雷游戏(多文件)

    C语言实现排雷游戏(多文件)

    这篇文章主要为大家详细介绍了C语言实现排雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • C++ OpenCV实战之制作九宫格图像

    C++ OpenCV实战之制作九宫格图像

    本文将为大家介绍如何使用OpenCV C++ 制作九宫格图像,即将一张图像均等分成九份,然后将这九个小块按一定间隔拷贝到新画布上就可以啦。感兴趣的可以动手试一试
    2022-01-01

最新评论