我试图启动另一个调用第一个进程并通过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();
// }
}
答案 0 :(得分:1)
您没有正确使用<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.20.1</version>
<extensions>true</extensions>
<configuration>
<images>
<image>
<alias>database</alias>
<name>mysql:5.7</name>
<run>
<wait>
<log>mysqld: ready for connections</log>
<time>20000</time>
</wait>
<env>
<MYSQL_ROOT_PASSWORD>abc123</MYSQL_ROOT_PASSWORD>
<MYSQL_DATABASE>testdb</MYSQL_DATABASE>
<MYSQL_USER>mysql</MYSQL_USER>
<MYSQL_PASSWORD>mysql</MYSQL_PASSWORD>
</env>
<ports>
<port>3306:3306</port>
</ports>
</run>
</image>
<image>
<name>mvndemo</name>
<build>
<from>java:8-jre</from>
<assembly>
<descriptorRef>artifact</descriptorRef>
</assembly>
</build>
</image>
</images>
</configuration>
<executions>
<execution>
<id>docker:start</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>docker:stop</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<mysql.jdbc.url>jdbc:mysql://${docker.host.address}/testdb</mysql.jdbc.url>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
。您的案例中的第二个参数是字符串文字MPI_Open_port
,而函数期望它是至少"A"
个元素的字符数组。这是一个输出参数,其中写入了实际的端口名称。传递常量字符串会导致访问冲突,因为字符串常量通常存储在现代操作系统的只读段中。
此外,MPI_MAX_PORT_NAME
和MPI_Comm_accept
的第一个参数应该是MPI_Comm_connect
返回的端口名称。由于端口名称可能每次都不同,因此MPI允许使用MPI_Open_port
在众所周知的服务名称下注册。然后可以将该已知名称传递给MPI_Publish_name
以获取端口。使用一些MPI实现使名称注册正常工作有点棘手,因此对于在同一节点上运行的进程,可以简单地将端口地址写入文件。显然,在调用MPI_Lookup_name
之前,您应该这样做。