Microsft MPI MPI_Isend中的死锁
Deadlock in Microsft MPI MPI_Isend
我有以下带有Microsoft MPI 的 c/c++ 代码
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main (int argc, char *argv[])
{
int err, numtasks, taskid;
int out=0,val;
MPI_Status status;
MPI_Request req;
err=MPI_Init(&argc, &argv);
err=MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
err=MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
int receiver=(taskid+1)% numtasks;
int sender= (taskid-1+numtasks)% numtasks;
printf("sender %d, receiver %d, rank %dn",sender,receiver, taskid);
val=50;
MPI_Isend(&val, 1, MPI_INT, receiver, 1, MPI_COMM_WORLD, &req);
MPI_Irecv(&out, 1, MPI_INT, sender, 1, MPI_COMM_WORLD, &req);
printf ("Rank: %d , Value: %dn", taskid, out );
err=MPI_Finalize();
return 0;
}
如果使用超过 2 个进程启动,应用程序将陷入死锁。通过 2 个进程,应用程序可以工作,但不执行"输出"写入。此代码适用于 linux mpi 发行版,问题似乎仅在微软版本中。有什么帮助吗?
首先,每个 MPI 进程执行两个通信:单个发送和单个接收。因此,您需要存储两个请求(MPI_Request req[2]
)和两个状态检查(MPI_Status status[2]
)。
其次,您需要在调用非阻塞发送/接收后等待,以确保它们正确完成。
MPI_Isend(&val, 1, MPI_INT, receiver, 1, MPI_COMM_WORLD, &req[0]);
MPI_Irecv(&out, 1, MPI_INT, sender, 1, MPI_COMM_WORLD, &req[1]);
// While the communication is happening, here you can overlap computation
// on data that is NOT being currently communicated, with the communication of val/out
MPI_Waitall(2, req, status);
// Now both the send and receive have been finished for this process,
// and we can access out, assured that it is valid
printf ("Rank: %d , Value: %dn", taskid, out);
至于为什么这适用于 Linux 发行版,而不是Microsoft发行版......我只能假设在底层,Linux 实现正在有效地将非阻塞通信实现为阻塞通信。也就是说,他们在"作弊",并在应该完成之前为您完成沟通。这使得他们更容易,因为他们不必跟踪太多关于通信的信息,但它也破坏了你重叠计算和通信的能力。你不应该依赖这个来工作。
相关文章:
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- 用C++中的std::condition_variable将线程置于死锁中会有风险吗
- 使用 std::async 时死锁,将来作为成员
- 如何调试读写器锁的死锁?
- 为什么在Visual Studio 2013上的std::this_thread::sleep_for上死锁
- localtime() 函数正在调用 ___lll_lock_wait_private(),这会使线程陷入死锁
- 如何重现 Boost 进程文档提示的死锁?
- 多线程Windows GUI应用程序中的死锁
- 为什么printf会导致与future.get的死锁,而cout则不会?
- C++中具有阻塞队列和障碍的死锁
- 死锁使用 std::mutex 来保护多个线程中的 cout
- 避免并发等待对象中的死锁
- 在VC++中从DLLMAIN内部调用D3D的CREATEDEVICE时,它会创建一个死锁(loaderlock?)。有没有办法克服这个问题?最终目标内
- 当用2个螺纹锁定时,将recursive_mutex死锁
- 程序在 C++11 中使用条件变量进入死锁
- 如何使用Boost MPI(我使用MPICH编译器)具有死锁场景
- Microsft MPI MPI_Isend中的死锁
- 带有MPI的主从模型中的死锁
- MPI::COMM::Create之后的死锁(所有进程终止)