如何使用 boost MPI 出现死锁情况(我使用 MPICH 编译器)?

How to have a deadlock scenario with boost MPI (I use MPICH compiler)?

我试图找出在什么情况下潜在阻塞的 boost mpi "send" 会实际阻塞并导致死锁。

#include <boost/mpi.hpp>
#include <iostream>

int main(int argc, char *argv[])
{
  boost::mpi::environment env{argc, argv};
  boost::mpi::communicator world;
  if (world.rank() == 0)
  {
    char buffer[14];
    const char *c = "Hello, world from 1!";
    world.send(1, 1, c, 13);
    std::cout << "1--11111\n";
    world.send(1, 1, c, 13);
    std::cout << "1--22222\n";
    world.recv(1, 1, buffer, 13);
    std::cout << "1--33333\n";
    world.recv(1, 1, buffer, 13);
    std::cout << "1--44444\n";
     buffer[13] = '[=10=]';
    std::cout << buffer << "11 \n";
  }
  else
  {
    char buffer[14];
    const char *c = "Hello, world from 2!";
    world.send(0, 1, c, 13);
    std::cout << "2--11111\n";
    world.send(0, 1, c, 13);
    std::cout << "2--22222\n";
    world.recv(0, 1, buffer, 13);
    std::cout << "2--33333\n";
    world.recv(0, 1, buffer, 13);
    std::cout << "2--44444\n";
    buffer[13] = '[=10=]';
    std::cout << buffer << "22 \n";
  }
}

但它运行得很好并且按照这个顺序:

2--11111
2--22222
1--11111
1--22222
1--33333
1--44444
Hello, world 11 
2--33333
2--44444
Hello, world 22

如果有人能给我一个我实际上陷入僵局的场景,我将不胜感激。 潜在阻塞的 boost mpi 是如何工作的?

谢谢。

通常最简单的强制阻止行为的方法是使用更大的消息,导致切换到所谓的 'rendezvous' 协议,发件人将等待收件人 post 匹配在开始数据传输之前接收操作。

实施可能会也可能不会完成 MPI_Send 在发布接收之前。您的代码不是正确的 MPI 应用程序。在下雨的满月期间,在特定的网络上,它可能会因特定的消息大小而死锁。

实际上,它主要取决于消息大小,因为实现通常会将小消息发送到预分配的缓冲区。根据您的实施,可能会有调整参数。

MPI 描述了几种通信模式。默认是 blocking1standard 模式,如上所述。 同步 发送 (MPI_Ssend) 必须等待接收被发布。这将保证死锁。

A buffered 发送 (MPI_Bsend) 必须完成,即使未发布接收也是如此。除了这些模式之外,还有 nonblockingimmediate 调用将始终在本地完成,但可能尚未复制数据。两者都将保证不会出现死锁。但是 boost.MPI.

只支持后者

1: blocking 在术语中仅表示调用阻塞,直到可以重新使用发送缓冲区。要么因为它被发送了,要么因为它被本地缓冲了。另请查看 the standard