在虚拟机中使用 Debian 12 和 CentOS 7 之间的
kill(pid, SIGINT)
时,我的代码行为存在差异。以前,此代码在 Fedora 39 中按预期工作。
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <cstdlib>
#include <cstring>
#include <sys/wait.h>
using namespace std;
void sigint_handler(int signal) {
cout << "The child process received the SIGINT signal. Ending..." << endl;
exit(EXIT_SUCCESS);
}
int main() {
pid_t pid = fork();
if (pid < 0) {
cerr << "Error creating the child process." << endl;
exit(EXIT_FAILURE);
} else if (pid == 0) {
// Child process
cout << "Child process created. PID: " << getpid() << endl;
// Signal handler for SIGINT
signal(SIGINT, sigint_handler);
// Executing ping for 10 iterations, although parent process should stop it earlier
execl("/bin/sh", "sh", "-c", "ping -c 10 google.com", NULL);
} else {
// Parent process
cout << "parent process. PID from child: " << pid << endl;
sleep(3); // Wait 3 seconds before sending the SIGINT
cout << "Sending SIGINT to the child process..." << endl;
if (kill(pid, SIGINT) == -1) {
cerr << "Error sending SIGINT to the child process." << endl;
exit(EXIT_FAILURE);
}
int status;
waitpid(pid, &status, 0); // Wait to the child process to end
if (WIFEXITED(status)) {
cout << "Child process end with status: " << WEXITSTATUS(status) << endl;
} else {
cout << "Child process end in an incorrect way" << endl;
}
}
return 0;
}
迁移到 Debian 12 后,上面的代码片段的行为不符合预期。它不会在发送 SIGINT 信号后停止 ping 进程,而是继续执行所有 10 次迭代。然而,当在 CentOS VM 中运行相同的代码时,它的行为正确,在几次迭代后停止。
为什么会出现这种情况?
提前致谢。
附加信息:
Debian 12 中的 g++ 版本:g++ (Debian 12.2.0-14) 12.2.0CentOS 7 虚拟机中的 g++ 版本:g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
编辑1:
我也尝试过用
system("ping -c 10 google.com")
代替
execl()
,但没有成功。除此之外,该问题与 Debian 和基于 Red Hat 的发行版中
ping
的不同实现无关,因为我已经尝试过我的原始代码并且它不会停止。在我的原始代码中,我调用了具有无限循环的
ping
,而不是
program.o
,应使用
Ctrl+C
停止该循环。在 Fedora 和 CentOS 中,我的程序运行完美,但在 Debian 中则不然。
// Signal handler for SIGINT
signal(SIGINT, sigint_handler);
// Executing ping for 10 iterations, although parent process should stop it earlier
execl("/bin/sh", "sh", "-c", "ping -c 10 google.com", NULL);
execl
将在新进程中将信号操作重置回默认值。这仅针对极短的窗口将信号处理程序设置为
sigint_handler
。因此,
ping
对
SIGINT
的反应完全取决于它如何设置其信号处理程序。据推测,不同的虚拟机具有不同的
ping
实现或版本。
iputils
和
inetutils
都有一个
ping
。