NCSA Home
Contact Us | Intranet | Search

ncsa

Avoiding Deadlock

  1. Deadlock Examples
  2. 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.

1.0 Deadlock Examples

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)

2.0 Some Solutions

An unsafe communication can be made into a safe one using any of these approaches:

  1. Reorder the communciations as shown in the third example above, where a SEND is matched by a RECV in that order.

  2. 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)

  3. 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

  4. 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)