【问题标题】:Thread synchronization with MPI使用 MPI 进行线程同步
【发布时间】:2011-11-03 17:58:54
【问题描述】:

我正在尝试将线程与 MPI 一起使用。该程序为 rank = 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();
}

【问题讨论】:

  • 您能否展示您如何启动程序以及您获得的输出?

标签: c multithreading mpi


【解决方案1】:

所提供的 MPI 线程级支持不是您所要求的,因为您的 MPI 库未使用它编译和安装。提供的支持价值是您的图书馆可以为您提供的,而不是您所要求的。所以这个值并不总是等于或大于要求的值。 例如,对于 OpenMPI,您必须使用选项 --enable-mpi-thread-multiple 对其进行配置

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

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

如果它说 mpi: no,你就没有机会支持多线程

【讨论】:

    【解决方案2】:

    我不太确定你是如何运行这个程序的,但我假设你运行多个进程并创建多个线程。话虽如此,您的问题在于这一行:

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

    它阻塞的原因是因为你设置它的方式,进程 0 正在向自己发送一条消息,所以它会等待自己接收消息,这变成了一个永无止境的等待游戏。

    尝试重新编写您的代码,确保您在正确的地方发送/接收,如果您还有问题,请告诉我们。

    【讨论】:

      猜你喜欢
      • 2018-03-10
      • 2011-04-15
      • 1970-01-01
      • 2014-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      相关资源
      最近更新 更多