mpi阻塞型函數的死鎖

 1. 總會死鎖的情形
 CALL MPI_COMM_RANK(comm, rank, ierr)
 IF (rank.EQ.0) THEN
  CALL MPI_RECV(recvbuf, count, MPI_REAL, 1, tag, comm, status, ierr)
  CALL MPI_SEND(sendbuf, count, MPI_REAL, 1, tag, comm, ierr)
 ELSE IF( rank .EQ. 1)
  CALL MPI_RECV(recvbuf, count, MPI_REAL, 0, tag, comm, status, ierr)
  CALL MPI_SEND(sendbuf, count, MPI_REAL, 0, tag, comm, ierr)
 END IF
講解:

  進程0的第一條接收語句A能否完成取決於進程1的第二條發送語句D,即A依賴於D,從執行次序上可以明顯地看出,進程0向進程1發送消息的語句C的執行又依賴於它前面的接收語句A的完成,即C依賴於A;同時,進程1的第一條接收語句B能否完成取決於進程0的第二條發送語句C的執行,即B依賴於C,從執行次序上可以明顯地看出,向進程0發送消息的語句D的執行又依賴於B的完成,故有A依賴於D,而D又依賴於B,B依賴於C,C依賴於A,形成了一個環,進程0和進程1相互等待,彼此都無法執行下去,必然導致死鎖。

圖7-1 總會死鎖的情形


2.可能死鎖的情形
 CALL MPI_COMM_RANK(comm, rank, ierr)
 IF (rank.EQ.0) THEN
  CALL MPI_SEND(sendbuf, count, MPI_REAL, 1, tag, comm, ierr)                                   A
  CALL MPI_RECV(recvbuf, count, MPI_REAL, 1, tag, comm, status, ierr)                     C
 ELSE (rank .EQ.1)
  CALL MPI_SEND(sendbuf, count, MPI_REAK, 0, tag, comm, status, ierr)                    B
  CALL MPI_RECV(recvbuf, count, MPI_REAL, 0, tag, comm, status, ierr)                      D
 END IF


圖7-2 可能死鎖的情形

  由於進程0或進程1的發送需要系統提供緩衝區(在MPI的四種通信模式中有詳細的解釋),如果系統緩衝區不足,則進程0或進程1的發送將無法完成,相應的,進程1和進程0的接收也無法正確完成。顯然對於需要相互交換數據的進程,直接將兩個發送語句寫在前面也是不安全的。

說明:當進程0發送的消息長度超過緩衝區大小時,要等到全部消息發送完成函數才能返回,在這種情況下,A的完成依賴於D的成功接收,而D的調用依賴於B的完成,B發送消息要等到C成功接收,而C的調用依賴於A的完成,從而造成彼此依賴,陷入死鎖。


3.可以避免死鎖的情形
CALL MPI_COMM_RANK(comm, rank, ierr)
IF (rank.EQ.0) THEN
 CALL MPI_SEND(sendbuf, count, MPI_REAL, 1, tag, comm, ierr)
 CALL MPI_RECV(recvbuf, count, MPI_REAL, 1, tag, comm, status, ierr)
ELSE (rank .EQ. 1)
 CALL MPI_RECV(recvbuf, count, MPI_REAL, 0, tag, comm, status, ierr)
 CALL MPI_SEND(sendbuf, count, MPI_REAL, 0, tag, comm, ierr)
END IF 

圖7-3 可以避免死鎖的情形

C的完成只需要A完成,而A的完成只要有對應的D存在,則不需要系統提供緩衝區也可以進行,這裏恰恰滿足這樣的條件,因此A總能夠完成,因此D也一定能完成。當A和D完成後,B的完成只需要相應的C,不需要緩衝區也能完成,因此B和C也一定能完成,所以說這樣的通信形式是安全的。顯然A和C,D和B同時互換,從原理上說和這種情況是一樣的,因此也是安全的。













   
 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章