【问题标题】:MPI and threadsMPI 和线程
【发布时间】:2011-11-02 09:01:17
【问题描述】:

我是 MPI 的初学者,我想通过以下方式在 MPI 中使用线程。某些进程(甚至所有进程)会产生线程并进行阻塞等待以接收消息。每个 proc 产生的线程数是一个命令行参数。因此,如果有 4 个 proc,则进程 0 和 2 会产生一个线程。现在,我希望进程 0 和 2 都向所有线程发送消息。例如,进程 0 向自身 AND 向进程 2 发送消息,而 proc 2 将消息发送给 proc 0 和自身。 这是我的代码的样子,它显然没有达到预期的效果。它只是等待接收消息。我哪里错了?

谢谢!

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

【问题讨论】:

    标签: c mpi


    【解决方案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 后执行 join。

    希望这会有所帮助。

    【讨论】:

    • 感谢 crisbia,但我希望平均排名发送消息。所以它必须是(rank%2==0)。我试图让相同的进程在其线程上发送和接收消息,我不知道这是否可能。
    • 我明白了。这是可能的,但您必须遵循我回答最后一部分的建议。基本上你需要产生线程,然后不要加入,因为它们会在接收时被阻塞。在进程的主线程(调用'spawn_thread'的那个线程中,执行发送(就像你已经做的那样),然后在线程上执行Join。也许你可以让spawn_threads使用'fd'和'threads'作为全局变量,这样您可以从主函数访问它们并加入线程并释放结构。
    • 感谢 crisbia,我完全删除了 join 并稍微修改了代码。我只是在尝试使用线程和 mpi,以便更好地理解这些概念。新代码似乎被阻塞了,我不知道为什么。这里是:[链接]stackoverflow.com/questions/7191907/…
    猜你喜欢
    • 1970-01-01
    • 2012-09-03
    • 2018-01-16
    • 2011-09-28
    • 2013-02-07
    • 2011-10-03
    • 2018-07-05
    • 1970-01-01
    相关资源
    最近更新 更多