与MPI线程同步(Thread synchronization with MPI)

2019-10-29 05:46发布

我试图使用线程与MPI。 此程序产生一个线程用于秩= 0,并发送和接收消息(阻塞),以及从所述线程。 线程的数目是命令行输入。 此代码然而在块发送/接收,就如何解决这一问题的任何想法? 此外,线程级安全我收到的是MPI_THREAD_SINGLE,不是我要求MPI_THREAD_MULTIPLE。 犯规_SINGLE究竟意味着只能有一个是每个进程执行的进程? 那么为什么有一个以上的线程输出显示接收到的消息两个线程?

谢谢!

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

Answer 1:

所提供的MPI线程级的支持是不是你问,因为您的MPI库编译时不与它安装一个。 所提供的支持值是你的库可以给你,而不是必要你的要求。 所以这个值并不总是比所需的值等于或greather。 例如,对于的openmpi,你必须使用选项--enable-MPI线程多配置它

你可以用这个命令来检查:

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

如果说MPI:不,你没有机会拥有多线程支持



Answer 2:

我不太清楚你是怎么运行这个程序,但我假设有多个进程正在运行,并创建多个线程。 有了这样说,你的问题是这一行:

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

它是阻塞的原因是因为你拥有了它的设置方式,进程0发送消息给自身,所以它会等待自己recv的消息,这变成一个永无止境的等待游戏。

尝试和返工你的代码,确保您的发送/接收到/从正确的地方,如果你有问题了,让我们知道。



文章来源: Thread synchronization with MPI