英文:
excevp does not take over child process (C++)
问题
以下是翻译好的代码部分:
我正在尝试在我的代码中将Stockfish引擎作为子进程运行。我想使用fork()和execvp()来实现这一点。我通过运行以下命令临时将Stockfish可执行文件的位置添加到我的PATH中:
export PATH="~/Apps/stockfish_15_linux_x64_avx2:$PATH"
我通过运行`echo $PATH`来确认这已经添加到PATH。我还可以在当前终端会话中的任何目录中运行Stockfish可执行文件,因此这一部分似乎正在工作。我遇到的问题是使用execvp从另一个可执行文件运行Stockfish。
我有以下代码来复现这个问题:
```c
#include <iostream>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main(void ) {
const char* argv[] = {"stockfish_15_x64_avx2", "d", NULL};
int pid = fork();
if (pid < 0) {
printf("Failed to fork");
}
else if (pid == 0){
execvp(argv[0], (char* const*)argv);
}
sleep(1);
printf("Finished executing the parent process\n"
" -- The child won't get here -- you will only see this once.\n");
return 0;
}
在Stockfish中,d
命令显示当前位置的图表。在这种情况下,这将是起始位置。但我得到的输出不是这个图表,而是:
Finished executing the parent process
-- The child won't get here -- you will only see this once.
Finished executing the parent process
-- The child won't get here -- you will only see this once.
这告诉我execvp实际上没有接管子进程。当我将参数更改为一个更通用的命令,比如argv[] = {"ls", "-a", NULL}
时,代码按预期工作。您知道这里发生了什么吗?
<details>
<summary>英文:</summary>
I am trying to run the stockfish engine as a child process in my code. I want to use fork() and execvp() to do this. I temporarily add the location of the stockfish executable to my PATH by running the command
``` export PATH="~/Apps/stockfish_15_linux_x64_avx2:$PATH" ```
And I checked to make sure this is added to PATH by running `echo $PATH`. I can also run the stockfish executable from any directory during my current terminal session, so this part seems to be working. What I am having trouble with is running stockfish from another executable using execvp.
I have the following code that reproduces the bug.
#include <iostream>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main(void ) {
const char* argv[] = {"stockfish_15_x64_avx2", "d", NULL};
int pid = fork();
if (pid < 0) {
printf("Failed to fork");
}
else if (pid == 0){
execvp(argv[0], (char* const*)argv);
}
sleep( 1 );
printf("Finished executing the parent process \n"
" -- The child won't get here -- you will only see this once. \n");
return 0;
}
the `d` command in stockfish displays a diagram of the current position. This would be the start position in this case. But instead of getting this diagram, the output I get is simply
<!-- language: lang-none -->
Finished executing the parent process
-- The child won't get here -- you will only see this once.
Finished executing the parent process
-- The child won't get here -- you will only see this once.
What this tells me is that execvp is not actually taking over the child process. When I change the arguments to a more generic command like `argv[] = {"ls", "-a", NULL}` then the code works as expected. Any idea what is going on here?
</details>
# 答案1
**得分**: 1
我开始使用waitpid进行一些错误处理,当时我有一种直觉,认为可执行文件名中的下划线可能是问题的原因。果然,当我将可执行文件重命名为'stockfish15'时,一切都按预期工作了。
代码现在看起来像这样:
```c
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
int main(void ) {
const char* argv[] = {"stockfish15", "d", NULL};
pid_t pid = fork();
if (pid == -1) {
printf("Failed to fork");
}
else if (pid == 0) {
execvp(argv[0], (char* const*) argv);
}
int status;
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
printf("子进程正常终止\n");
}
else {printf("exevp错误\n");}
printf("父进程执行完毕\n"
" -- 子进程不会执行到这里 -- 你只会看到这一次。\n");
return 0;
}
输出结果为:
Stockfish 15由Stockfish开发者创建(请参阅AUTHORS文件)
+---+---+---+---+---+---+---+---+
| r | n | b | q | k | b | n | r | 8
+---+---+---+---+---+---+---+---+
| p | p | p | p | p | p | p | p | 7
+---+---+---+---+---+---+---+---+
| | | | | | | | | 6
+---+---+---+---+---+---+---+---+
| | | | | | | | | 5
+---+---+---+---+---+---+---+---+
| | | | | | | | | 4
+---+---+---+---+---+---+---+---+
| | | | | | | | | 3
+---+---+---+---+---+---+---+---+
| P | P | P | P | P | P | P | P | 2
+---+---+---+---+---+---+---+---+
| R | N | B | Q | K | B | N | R | 1
+---+---+---+---+---+---+---+---+
a b c d e f g h
Fen: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
密钥:8F8F01D4562F59FB
检查者:
子进程正常终止
父进程执行完毕
-- 子进程不会执行到这里 -- 你只会看到这一次。
尽管如此,我仍然想知道为什么会发生这种情况的解释。
英文:
So I was starting to use waitpid to do some error handling, when I had a hunch that the underscores in the executable name were somehow the problem. And sure enough, when I renamed the executable to 'stockfish15' everything works as intended.
The code now looks like this
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
int main(void ) {
const char* argv[] = {"stockfish15", "d", NULL};
pid_t pid = fork();
if (pid == -1) {
printf("Failed to fork");
}
else if (pid == 0) {
execvp(argv[0], (char* const*) argv);
}
int status;
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
printf("child terminated normally\n");
}
else {printf("exevp error\n");}
printf("Finished executing the parent process \n"
" -- The child won't get here -- you will only see this once. \n");
return 0;
}
and the output is
<!-- language: lang-none -->
Stockfish 15 by the Stockfish developers (see AUTHORS file)
+---+---+---+---+---+---+---+---+
| r | n | b | q | k | b | n | r | 8
+---+---+---+---+---+---+---+---+
| p | p | p | p | p | p | p | p | 7
+---+---+---+---+---+---+---+---+
| | | | | | | | | 6
+---+---+---+---+---+---+---+---+
| | | | | | | | | 5
+---+---+---+---+---+---+---+---+
| | | | | | | | | 4
+---+---+---+---+---+---+---+---+
| | | | | | | | | 3
+---+---+---+---+---+---+---+---+
| P | P | P | P | P | P | P | P | 2
+---+---+---+---+---+---+---+---+
| R | N | B | Q | K | B | N | R | 1
+---+---+---+---+---+---+---+---+
a b c d e f g h
Fen: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
Key: 8F8F01D4562F59FB
Checkers:
child terminated normally
Finished executing the parent process
-- The child won't get here -- you will only see this once.
Still, I'd like to know the explanation for why this is happening.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论