2017-04-02 63 views
-1
#include "stdafx.h" 
#include <mpi.h> 
#include <stdio.h> 
#include <iostream> 
#include <fstream> 
#include <string> 
#include <cctype> 
#include <cstdlib> 
#include <ctime> 
#include <cctype> 
#include <cstdlib> 
#include <ctime> 
using namespace std; 

int randomize() { 
    srand(time(0)); 
    int i = 1 + rand() % 3; 
    return i; 
} 

int main(int argc, char** argv) { 
    MPI_Init(&argc, &argv); 
    int rank, size, tag = 1; 
    ofstream outfile; 
    ifstream infile; 
    bool read = true; 
    const int max = 10; 
    char message[max]; char msgS[max]; char msgR[max]; 

    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    outfile.open("in.txt"); 
    cout << "Write messages: " << rank << endl; 
    do { 
     cin.getline(message, max); 
     if (strcmp(message, "stop") == 0) 
      break; 
     outfile << message << endl; 
    } while (strcmp(message, "stop") != 0); 
    cout << "Messages written to file [in.txt]!" << endl; 
    outfile.close(); 

    infile.open("in.txt"); 
    outfile.open("out.txt"); 

    if (rank == 0 && read) { 
     int i = randomize(); 
     if (!infile.eof()) { 
      infile >> msgS; 
      MPI_Send(msgS, strlen(msgS), MPI_CHAR, (rank + i), tag, MPI_COMM_WORLD); 
      read = false; 
     } 
     else { 
      cout << "Messages written to file [out.txt]!" << endl; 
      infile.close(); 
      outfile.close(); 
      exit(0); 
     } 
    } 
    else if (rank == 1 && !read) { 
     MPI_Recv(msgR, strlen(msgS), MPI_CHAR, 0, tag, MPI_COMM_WORLD, MPI_STATUSES_IGNORE); 
     outfile << msgR << endl; 
     tag++; 
     read = true; 
    } 
    else if (rank == 2 && !read) { 
     MPI_Recv(msgR, strlen(msgS), MPI_CHAR, 0, tag, MPI_COMM_WORLD, MPI_STATUSES_IGNORE); 
     outfile << msgR << endl; 
     tag++; 
     read = true; 
    } 
    else if (rank == 3 && !read) { 
     MPI_Recv(msgR, strlen(msgS), MPI_CHAR, 0, tag, MPI_COMM_WORLD, MPI_STATUSES_IGNORE); 
     outfile << msgR << endl; 
     tag++; 
     read = true; 
    } 
    else { 
     cout << "Error!!!"; 
     exit(0); 
    } 
    MPI_Finalize(); 
    system("PAUSE"); 
    return 0; 
} 

有問題。代碼停在MPI_Send例程處,我不知道爲什麼!只需要將一個讀取行從文件發送到任何進程,並將接收到的數據存儲到另一個文件中。如何調試非工作MPI發送?

+0

'randomize' returns大於3的數字,所以你最終得到一個沒有匹配'Recv'的'Send'(這是因爲你使用的是發送和接收的阻塞版本) – niceman

+0

關於每個等級的if語句對你來說合法嗎? –

+0

對不起,我錯了,讓我想想吧 – niceman

回答

0

問題並不明顯,但很簡單,它是read變量。

的事情是,你在代碼中所有的進程將執行設置readtrue和你不改變它以後,因爲這個這個,如果身體:

if(rank==0 && read) 

將執行上第一個過程,其等級爲0和讀是true但身體這樣,如果:

if(rank ==1 && !read) 

甚至不會在過程中執行秩因爲1!read是假的。

的問題是,所述第一if包含阻隔外界MPI_Send呼叫這意味着它將阻塞進程執行,直至預定的接收機呼叫MPI_Recv和永遠不會發生由於接收過程的非到達MPI_Recv,因爲它們的if'條件總是錯誤的(!read在您的代碼中始終爲false)。

所以解決方案:有很多,但我建議完全刪除read變量。

如果對您有必要,您必須找出一種方法將其設置爲阻止發件人進程和接收者進程的值,注意MPI_Recv也被阻止,它將阻塞,直到預期發件人發送信息,所以如果該發件人沒有達到MPI_Send接收器將只是掛出等待。

最後但並非最不重要,而並非是你的問題的解決方案,你可以看非阻塞發送-RECV,他們被稱爲MPI_ISendMPI_IRecv,不使用這些作爲解決whatever hanging problem I find,他們不意思是爲了做一些計算,而當消息得到發送時,當這些計算不受消息影響時,對於受消息影響的任何計算,您必須調用MPI_Wait(或其任何朋友)

+0

我認爲非阻塞調用非常有用,特別是對於避免死鎖和不必要的同步。無論如何,MPI庫通常不能重疊通用硬件上的通信和計算。 –

+0

@VladimirF我很害怕「嗯,它掛了,只是加上'I'',它不只是一個'I',它需要不同的思維方式,是的,它們非常有用,幾乎應該總是使用,但是當你在完成「ISend/IRecv」後立即調用'MPI_Wait'(或朋友)我寧願只使用阻塞函數 – niceman