gpt4 book ai didi

c++ - fork/pipes 和运行多个程序

转载 作者:太空宇宙 更新时间:2023-11-04 03:08:55 25 4
gpt4 key购买 nike

我前段时间为游戏“draughts”编写了一个引擎,现在我想编写一个程序,通过某种协议(protocol)与其中两个引擎进行通信。最后,我希望有一些类似于 UCI 协议(protocol)的东西,它在国际象棋引擎的程序员中广为人知。

引擎应该通过 stdin 接收所有命令并通过 stdout 发送它的响应。

我创建了一些虚拟引擎来测试它,在 if 语句之前进行一些测试,看看引擎是否收到任何东西。

int main(){

std::cerr<<"MainEngine"<<std::endl;
while (!std::cin.eof()) {
std::string current;
std::getline(std::cin, current);
std::cerr<<"FromMain:"<<current<<std::endl;
if (current == "init") {
initialize();
std::cout << "ready" << "\n";
} else if (current == "hashSize") {
std::string hash;
std::getline(std::cin, hash);
setHashSize(1u << std::stoi(hash));
} else if (current == "position") {
std::string position;
std::getline(std::cin, position);
} else if (current == "move") {
std::string move;
std::getline(std::cin, move);
}
}

return 0
}

这是我尝试使用管道进行通信的部分

 struct Interface {
enum State {
Idle, Ready, Searching
};
const int &engineRead1;
const int &engineRead2;
const int &engineWrite1;
const int &engineWrite2;
State oneState;
State twoState;

void initEngines();

void writeMessage(const int &pipe, const std::string &message);

void processInput(const int &readPipe);

Interface &operator<<(const std::string message);

};

void Interface::processInput(const int &readPipe) {
std::string message;
char c;
while ((read(readPipe, &c, sizeof(char))) != -1) {
if (c == '\n') {
break;
} else {
message += c;
}
}
if (message == "ready") {
std::cout << "ReadyEngine" << std::endl;
}
}

void Interface::writeMessage(const int &pipe, const std::string &message) {
write(pipe, (char *) &message.front(), sizeof(char) * message.size());
}


int main(int argl, const char **argc) {
int numEngines = 2;
int mainPipe[numEngines][2];
int enginePipe[numEngines][2];

for (auto i = 0; i < numEngines; ++i) {
pipe(mainPipe[i]);
pipe(enginePipe[i]);


auto pid = fork();

if (pid < 0) {
std::cerr << "Error" << std::endl;
exit(EXIT_FAILURE);
} else if (pid == 0) {
dup2(mainPipe[i][0], STDIN_FILENO);
close(enginePipe[i][1]);
dup2(enginePipe[i][1], STDOUT_FILENO);
close(mainPipe[i][0]);
execlp("./engine", "engine", NULL);
}
close(enginePipe[i][0]);
close(mainPipe[i][1]);

std::string message = "init\n";
Interface inter{enginePipe[0][0], enginePipe[1][0], mainPipe[0][1], mainPipe[1][1]};
inter.writeMessage(inter.engineWrite1, message);
inter.writeMessage(inter.engineWrite2, message);

int status;
for (int k = 0; k < numEngines; ++k) {
wait(&status);
}
}
}

我正在为每个引擎创建两个子进程。在此测试中,我只是将“init\n”发送到每个引擎,并希望子进程打印“FromMain: init”。但是,我只从其中一个子进程获得输出“MainEngine”。

这是我第一次尝试使用管道,我不知道我哪里搞砸了。我将不胜感激有关如何正确设置通信部分的一些提示/帮助。

最佳答案

                close(enginePipe[i][1]);
dup2(enginePipe[i][1], STDOUT_FILENO);

您正在关闭管道,然后尝试复制它。这行不通。

            close(enginePipe[i][0]);
close(mainPipe[i][1]);

std::string message = "init\n";
Interface inter{enginePipe[0][0], enginePipe[1][0], mainPipe[0][1], mainPipe[1][1]};

并且您要关闭这些管道,然后再尝试使用它们。并在每次迭代时与所有管道进行 inter,而不是每个管道一次。

我建议你先用两个进程和一个管道做一些简单的事情,然后再尝试用三个进程和四个管道做这样复杂的事情。

关于c++ - fork/pipes 和运行多个程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58566369/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com