Avoiding Deadlock
- Deadlock Examples
- Some Solutions
You should be careful with your communications pattern to avoid getting into
a deadlock. A deadlock is a situation that arises when a process cannot
proceed because it is waiting on another process that is, in turn, waiting on
the first process.
Below is an example showing a communication pattern that leads to a
deadlock.
Process 0 Process 1
Recv(1) Recv(0)
Send(1) Send(0)
In this example, the RECV call is blocking. Therefore each process is waiting to
receive from the other and blocks there waiting for a corresponding send. The
send can never execute, and both processes are blocked at the RECV
resulting in a deadlock.
Another example that is unsafe to use is:
Process 0 Process 1
Send(1) Send(0)
Recv(1) Recv(0)
This situation is correct logically, but it depends on how the blocking is
implemented for the SEND and RECV. If SEND blocks until the data are
copied out of the sender buffer, then a deadlock can happen if the system
doesn't have enough buffer to allocate for both sends at the same time. If
the system can allocate enough buffer for both sends to go, then they will
return, and the RECV will start. The order depends on the system
resources and therefore is unsafe to use.
The following scenario is always safe because each SEND is matched by a
corresponding RECV before the other SEND starts.
Process 0 Process 1
Send(1) Recv(0)
Recv(1) Send(0)
An unsafe communication can be made into a safe one
using any of these approaches:
- Reorder the communciations as shown in the
third example above, where a
SEND is matched by a RECV in that order.
- Use the MPI_Sendrecv, which supplies the receive buffer at the same
time as the send buffer.
Process 0 Process 1
Sendrecv(1) Sendrecv(0)
- Use non-blocking ISend or IRecv.
The Send/Recv does
not block in this case, but you must check for compeletion of
communications before using the buffers:
Process 0 Process 1
ISend(1) ISend(0)
IRecv(1) IRecv(0)
Waitall Waitall
- Use the buffered mode BSend. This will insure that a user-supplied
buffer is allocated for Send regardless of system resources.
Process 0 Process 1
Bsend(1) Bsend(0)
Recv(1) Recv(0)