异步数据交换,除了阻塞函数 send() 和 recv() 之外,Boost.MPI 还支持与成员函数 isend() 和 irecv() 的异步数据交换。名称以 i 开头,表示函数立即返回。
示例 47.7。使用 irecv() 异步接收数据
#include#include #include #include 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#include #include #include 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++异步数据交换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!