c++ - 尝试启动另一个进程并通过 MPI 加入它但遇到访问冲突

标签 c++ windows mpi

我正在尝试启动另一个调用第一个进程并通过 MPI 加入它的进程,但我遇到了我无法弄清楚的访问冲突。我认为代码应该很容易解释,访问冲突发生在 MPI_COMM_ACCEPT 行。我认为一切看起来或多或少都符合要求,它应该可以工作,但不会。

如果我做的一切都错了并且有更简单的方法,请告诉我。我没有使用 mpiexec,因为我试图在构建整个困惑的测试框架中执行此操作,但如果这更有意义,那么就告诉我我把它搞砸了。

#include <windows.h>
#include <AtlBase.h>
#include <atlconv.h>
#include <iostream>
#include "mpi.h"
#include <string>
int main(int argc, char** argv)
{
    MPI_Init(&argc, &argv);
    MPI_Comm intercomm;
    if (argc == 1)
    {
        PROCESS_INFORMATION pi;
        STARTUPINFO si;
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));
        std::string x = std::string(argv[0]);
        x += " ";
        x += std::to_string(1);
        int res = CreateProcess(NULL, CA2T(x.c_str()), NULL, NULL, false, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
        std::cout << res <<std::endl;
        MPI_Open_port(MPI_INFO_NULL, "A");
        MPI_Comm_accept("A", MPI_INFO_NULL, 0, MPI_COMM_SELF,&intercomm);
        std::cout << MPI_Comm_size(intercomm, &res);
        std::cout << res;
    }
    else
    {
        MPI_Comm_connect("A", MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm);
    }
    MPI_Finalize();
    // }
}

编辑: 作品!这非常令人沮丧,但它确实有效!

#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <mpi.h>
#include <windows.h>
#include <AtlBase.h>
#include <atlconv.h>
#include <iostream>
#include "mpi.h"
#include <string>
int main(int argc, char** argv)
{
    char myPort[MPI_MAX_PORT_NAME];
    MPI_Init(&argc, &argv);
    MPI_Comm intercomm;
    if (argc == 1)
    {
        PROCESS_INFORMATION pi;
        STARTUPINFO si;
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));
        MPI_Open_port(MPI_INFO_NULL, myPort);
        std::string x = std::string(argv[0])+" \""+myPort+"\"";
        std::cout <<"OLDPROCESS:" << x << std::endl;
        int res = CreateProcess(NULL, CA2T(x.c_str()), NULL, NULL, false, NORMAL_PRIORITY_CLASS , NULL, NULL, &si, &pi);
        MPI_Comm_accept(myPort, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm);
        std::cout << MPI_Comm_size(intercomm, &res);
    }
    else
    {
        std::cout << "NEWPROCESS:"<<argv[1] << std::endl;
        strcpy_s(myPort,argv[1]);
        MPI_Comm_connect(myPort, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm);
    }
    MPI_Finalize();
    // }
}

最佳答案

您没有正确使用 MPI_Open_port。你的情况下的第二个参数是字符串文字 "A" 而函数期望它是至少 MPI_MAX_PORT_NAME 元素的字符数组。这是一个输出参数,实际的端口名称被写入其中。传递常量字符串会导致访问冲突,因为字符串常量通常存储在现代操作系统的只读段中。

此外,MPI_Comm_acceptMPI_Comm_connect 的第一个参数应该是 MPI_Open_port 返回的端口名称。由于端口名称可能每次都不同,MPI 允许使用 MPI_Publish_name 将其注册到众所周知的服务名称下。然后可以将该众所周知的名称传递给 MPI_Lookup_name 以获取端口。使名称注册正常工作对于某些 MPI 实现来说有点棘手,因此对于在同一节点上运行的进程,可以简单地将端口地址写入文件。您显然应该在调用 CreateProcess 之前执行此操作。

关于c++ - 尝试启动另一个进程并通过 MPI 加入它但遇到访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43858346/

相关文章:

c# - 如何在c#中保存和加载textBox字体?

c++ - 如何使用 Python 或 C++ 创建通用网络代理?

c++ - CMake 添加库 libpq (postgreSQL) mac c++ clion

c++ - 访问从模板类派生的类中的基本成员函数

c - 我如何使这个简单的 C 程序只用一个按键而不是两个按键重新启动

通过命令行的 Windows 照片查看器 - 特殊功能

c++ - 意外的 MPI 地址偏移

parallel-processing - 如何指定并行程序中哪些进程在哪个节点上运行

c - 如何使用openMP为MPI程序制作makefile?

c++ - 将两个#define 混合成一个词