2011-08-23 41 views
1

我是MPI的初學者,我想以下面的方式使用MPI的線程。某些進程(甚至是特克斯)產生線程並且阻塞等待接收消息。每個proc產生的線程數是一個命令行參數。所以如果有4個特效,進程0和2會產生一個線程。現在,我希望進程0和2都將消息發送到所有線程。例如,進程0向自己發送消息並向進程2發送消息,進程2將消息發送給進程0和自己。 這是我的代碼看起來像,它顯然不會做任何想要的。它只是等待收到消息。我哪裏錯了?MPI和線程

謝謝!

typedef struct { 
    int id; 
    } struct_t; 

void *hello(void *arg) 
{ 
    int rank; 
    char mystr[10]; 
    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); 

    if(rank%2 ==0){ 
      MPI_Recv(mystr, 10, MPI_CHAR, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status); 
      printf("Thread %d on rank %d received %s\n", fd->id, rank, mystr); 
    } 

    return (NULL); 
} 

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

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

    /* Start up thread */ 
    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], &pthread_custom_attr, hello, (void *)(fd+i)); 
    } 

    /* Synchronize the completion of each thread. */ 
    for (i=0; i<n; i++) 
    { 
      pthread_join(threads[i],NULL); 
    } 
    free(fd); 
} 
void main(int argc, char ** argv) 
{ 
    int n,i, provided, claimed; 
    int rank, size, errs; 

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

    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); 
    } 

    if(rank%2 == 0) 
      spawn_thread(n); 

    if(rank%2 == 0){ 

        printf("My rank is %d and I am sending Hello!\n", rank); 
        MPI_Send("HELLOOO", 10, MPI_CHAR, rank, 0, MPI_COMM_WORLD); 
      } 

    MPI_Finalize(); 
} 

回答

1

我不完全明白你正在嘗試什麼來實現的,但請並非所有的甚至排名進程的線程將阻塞接收,所以沒有人會運行發送代碼。你的奇數排名進程的線程只是立即開始和結束,因爲他們不會做任何事情。

也許以下,如果:

if(rank%2 == 0){ 
     printf("My rank is %d and I am sending Hello!\n", rank); 
     MPI_Send("HELLOOO", 10, MPI_CHAR, rank, 0, MPI_COMM_WORLD); 
    } 

應該是這樣的:

if(rank%2 != 0) 

這樣,你的排名奇數流程至少會發送命令?

或者,您需要將「join」代碼移到spawn_thread函數之外,並在調用send之後執行連接。

希望這會有所幫助。

+0

謝謝crisbia,但我想要偶數級別發送消息。所以它需要(排名%2 == 0)。我試圖在其線程上發送和接收相同的進程消息,我不知道這是否可能。 – cnovice

+0

我明白了。這是可能的,但你必須按照我答案的最後部分的建議。基本上你需要產生線程,然後不要加入,因爲他們將被阻止在接收。在進程的主線程(調用'spawn_thread'的線程,執行send(就像你已經做的那樣),然後在線程上執行Join。也許你可以讓spawn_threads使用'fd'和'threads'作爲全局變量,這樣你可以從主函數訪問它們並加入線程並釋放結構 – crisbia

+0

感謝crisbia,我完全刪除了連接,並修改了一些代碼,我只是想玩弄線程和mpi,以便更好地理解這些概念。新代碼似乎阻塞,我不知道爲什麼。這是它:[link] http://stackoverflow.com/questions/7191907/thread-synchronization-with-mpi [/ link] – cnovice