名为connect()的函数如何阻止MPI C程序运行?

chr*_*hvz 5 c program-entry-point runtime-error function mpi

我正在使用MPI编写一个项目用于并行编程课程,并决定命名我的一个函数connect().但每当我尝试使用mpirun该程序时(在Linux和OS X上使用最新版本的Open MPI)connect(),即使我没有connect()从中调用,我也会收到函数的输出main().另外,一些输出main()不会出现.

这是一个带有问题的简化程序:

#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>

void connect(); //function name breaks mpi

int main(void) {

    int comm_sz, my_rank;
    MPI_Init(NULL, NULL);
    MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    printf("my_rank is %d\n", my_rank);
    fflush(stdout);
    MPI_Finalize();
    return EXIT_SUCCESS;
}

void connect() {

    printf("\nNot main! \n");
    return;
}
Run Code Online (Sandbox Code Playgroud)

和输出:

[me@host ~]$ mpicc bad.c -Wall
[me@host ~]$ mpirun -n 1 a.out 

Not main! 
--------------------------------------------------------------------------
orterun noticed that process rank 0 with PID 17245 on node host exited on signal 13 (Broken pipe).
--------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

我一开始就问Stack Overflow首先出了什么问题,直到我发现重命名函数修复了它.所以我现在很好奇的是为什么命名该函数会connect()阻止程序正常运行.是否也是mpirun/ Open RTE 的问题?

可能的线索:

  • 有一个connect()函数<sys/socket.h>,但我还没有在MPI头文件中找到它.
  • 还有一个Connect()函数(带有一个大写的C),"ompi/mpi/cxx/intracomm.h"其间接包含<mpi.h>,但我认为在C/C++中很重要,它看起来像一个C++类的方法.
  • 如果我尝试像普通程序一样执行程序,它在OS X上运行时有效,但在Linux上运行时无效:

mac:~ me$ ./a.out 
my_rank is 0
Run Code Online (Sandbox Code Playgroud)

VS

[me@linux ~]$ ./a.out 

Not main! 
Run Code Online (Sandbox Code Playgroud)

elb*_*ows 7

我猜你调用的MPI函数之一就是调用connect()系统调用.但由于ELF可执行文件具有符号的平面命名空间,因此您connect()将被调用.

这个问题在Mac OS上不会发生,因为Mach-O库有两级命名空间,因此不同库中的符号不​​会相互冲突.

如果你使你的函数静态,那么也可能避免这个问题.

  • 作为Open MPI的作者之一,我将确认+ elbows提供的答案是正确的:Open MPI使用connect(2)系统调用.当你有一个名为connect(2)的公共函数(可能作为MPI_Init的一部分)时,链接器将最终调用*your*connect()函数而不是connect(2).坏事发生在那里. (2认同)