2011-08-25 3 views
0

MPI와 함께 스레드를 사용하려고합니다. 이 프로그램은 순위 = 0에 대한 스레드를 생성하고 스레드와 메시지를주고받습니다. 스레드 수는 명령 행 입력입니다. 그러나이 코드는 송수신을 차단하며이를 해결하는 방법에 대한 아이디어가 있습니까? 또한 내가받는 스레드 레벨 안전성은 MPI_THREAD_SINGLE이며, MPI_THREAD_MULTIPLE에 대한 요청이 아닙니다. _SINGLE은 프로세스 당 하나의 스레드 만 실행될 수 있다는 것을 의미합니까? 그렇다면 두 개 이상의 스레드가있는 출력에서 ​​두 스레드가 메시지를 받았음을 보여주는 이유는 무엇입니까?MPI와의 스레드 동기화

감사합니다.

typedef struct { 
     int id; 
} struct_t; 

void *getmsg(void *arg) 
{ 
    int rank; 
    char mystr[10]; 
    MPI_Request request; 
    MPI_Status status; 
    struct_t *fd=(struct_t *)arg; 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    printf("Rank %d is waiting in thread %d for my message\n", rank, fd->id); 
    while(1){ 
      MPI_Recv(mystr, 10, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); 
      if(status.MPI_TAG == 0){ 
        printf("Thread %d on rank %d received NULL from %d\n", fd->id, rank, status.MPI_SOURCE); 
        return; 
      } 
      printf("Thread %d on rank %d received %s from rank %d\n", fd->id, rank, mystr, status.MPI_SOURCE); 
    } 
    printf("I am now sending the string to rank 1\n"); 
    MPI_Send(mystr, 10, MPI_CHAR, 1, 2, MPI_COMM_WORLD); 

    return (NULL); 
} 

void spawn_thread(int n) 
{ 
    int rank, i; 
    pthread_t *threads; 
    pthread_attr_t pthread_custom_attr; 
    struct_t *fd; 
    threads=(pthread_t *)malloc(n*sizeof(threads)); 
    fd=(struct_t *)malloc(sizeof(struct_t)*n); 

    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    for (i=0; i<n; i++) 
    { 
      fd[i].id=i; 
    //  printf("My rank is %d and I created thread #%d\n", rank, i); 
      pthread_create(&threads[i], NULL, getmsg, (void *)(fd+i)); 
    } 

    free(fd); 
} 

void main(int argc, char ** argv) 
{ 
    int n,i, provided, claimed; 
    int rank, size, errs; 

    int main; 

    MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    char mystr[10]; 
    MPI_Status status; 

    if(rank==0 && provided<MPI_THREAD_MULTIPLE){ 
      printf("You get %d level thread safety, not %d\n",provided, MPI_THREAD_MULTIPLE); 
    } 
    if (argc != 2) 
    { 
      printf ("Usage: %s n\n where n is no. of threads\n",argv[0]); 
      exit(1); 
    } 

    n=atoi(argv[1]); 
    if ((n < 1) || (n > MAX_THREAD)) 
    { 
      printf ("The no of thread should between 1 and %d.\n",MAX_THREAD); 
      MPI_Abort(MPI_COMM_WORLD,-1); 
} 

    MPI_Request request; 
    if(rank == 0){ 
      spawn_thread(n); 
    } 

    printf("Rank %d says hello\n",rank); 
    MPI_Send("HELLO!!!", 10, MPI_CHAR, 0, 1, MPI_COMM_WORLD); 

    printf("Rank %d is sending Null\n",rank); 
    if(rank==0) 
      MPI_Send(NULL,0,MPI_CHAR,0,0,MPI_COMM_WORLD); 

    MPI_Recv(mystr, 10, MPI_CHAR, 0, 2, MPI_COMM_WORLD,&status); 
    printf("I am rank %d and I received %s \n",rank, mystr); 

    MPI_Finalize(); 
} 
+0

출력과 함께 프로그램을 시작하는 방법을 보여줄 수 있습니까? – Quantumboredom

답변

0

이 프로그램을 어떻게 실행하는지 잘 모르겠지만 여러 프로세스로 실행하고 여러 스레드를 만드는 것으로 가정합니다. 그는 말했다되고으로, 당신의 문제는이 라인이다 :

MPI_Send("HELLO!!!", 10, MPI_CHAR, 0, 1, MPI_COMM_WORLD); 

당신이 가지고있는 방법은 설정, 프로세스 0 자체로 메시지를 전송하고, 그래서 자체 대기하므로이 차단되는 이유는 recv 메시지는 결코 끝나지 않는 대기 게임으로 변합니다.

코드를 다시 작성하고 올바른 장소로 보내거나받는 곳에서 송수신을 확인하십시오. 더 이상 문제가 없으면 저희에게 알려주십시오.

3

제공된 MPI 스레드 수준 지원은 MPI 라이브러리가 컴파일되지 않았기 때문에 요청한 것이 아닙니다. 제공된 지원 가치는 귀하의 도서관에서 귀하에게 제공 할 수있는 것이며 귀하가 요구하는 것은 아닙니다. 따라서이 값은 항상 필요한 값보다 크거나 같지 않습니다. 예를 들어, OpenMPI 실행을 위해, 당신은 당신이 명령으로 확인할 수있는 옵션 --enable-MPI-스레드 여러

으로 구성해야합니다 :

shell$ ompi_info | grep -i thread 
     Thread support: posix (mpi: yes, progress: no) 

는 MPI 말한다면 : 아니, 다중 스레드 지원을 할 수있는 기회가 없습니다.