【发布时间】:2017-12-26 13:02:39
【问题描述】:
我的 Windows 机器上有一个使用 MinGW 的 gcc 编译的可执行文件 loop.exe。
loop.c 的代码在行为上类似于:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
static int sigintReceived = 0;
void sigint_handler(int signum){
sigintReceived = 1;
}
int main(){
signal(SIGINT, sigint_handler);
while(1){
sleep(1);
if(sigintReceived){
printf("SIGINT received");
exit(0);
}
}
}
如果我使用 Cygwin.bat 打开 Cygwin 终端并运行 ./loop.exe 然后按 Ctrl+C 我将看到输出:
SIGINT received
但是,如果我使用 Cygwin.bat 打开 两个 终端并在其中一个中运行 ./loop.exe 并在另一个中运行 kill -2 <LOOP_EXE_PID>,我根本看不到输出.
当我使用 any 信号和处理程序运行 kill -## <LOOP_EXE_PID> 时,代码就像不存在信号处理程序一样(例如,如果我 kill -10 我会得到一个 Bus error 或者如果我kill -12 我会得到一个Bad system call 或者如果我kill -11 我会得到一个Segmentation fault)
我环顾四周,遇到了this answer,我认为这可能与我遇到的情况有关,但是loop.exe 在每种情况下都被终止了。在这个答案中,Bogdan 提到 Windows 可执行文件不是由 Bash shell 直接运行,而是通过中间 Bash 进程运行,当我运行./loop.exe 时,我可以在 Windows 任务管理器中看到这个进程,但我看不到这个中间 Bash 进程从 Cygwin 内部。
关于如何让kill -2 <LOOP_EXE_PID> 发挥与 Ctrl+C 相同的作用的任何想法?或者,有什么想法可以让我从 Cygwin 内部看到这个中间 Bash 进程?
注意:我正在使用C:\cygwin\Cygwin.bat 运行 Cygwin;我不使用薄荷糖。
【问题讨论】:
-
我认为运行两个cygwins与在同一个linux系统上运行两个终端是不一样的。我认为这就像运行两个不同的系统。不过不确定。可以在另一个的
ps中看到其中一个的 PID 吗? -
@EugeneSh。是的,PID 在不同的 Cygwin 终端之间是一致的。
-
使用信号处理程序中的标准库函数会调用未定义的行为。标准库不保证是线程安全的。
-
@Olaf 我明白,但这不是重点。将
printf("SIGINT received\n");替换为您想要的任何语句,该语句仍然不会被调用/执行。为了便于理解,我使用了printf,尽管我知道这是不好的做法。 -
“不良做法”与未定义的行为不同!使用调试器让您感到舒适。
标签: c windows cygwin mingw signal-handling