我的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>
,我根本看不到输出。
当我使用任何信号和处理程序运行kill -## <LOOP_EXE_PID>
时,代码就像不存在信号处理程序一样(例如,如果我kill -10
我会得到一个Bus error
,或者如果我kill -12
我会得到一个Bad system call
或者如果我kill -11
我会得到一个Segmentation fault
(
我环顾四周,发现了这个答案,我相信这可能与我遇到的问题有关,但是loop.exe
在每种情况下都被终止了。在这个答案中,Bogdan提到Windows可执行文件不是由Bash shell直接运行的,而是通过中间的Bash进程运行的,当我运行./loop.exe
时,我可以在我的Windows任务管理器中看到这个过程,但我无法从Cygwin内部看到这个中间Bash进程。
关于如何让kill -2 <LOOP_EXE_PID>
与Ctrl+C相同的操作的任何想法?或者,我如何从Cygwin内部看到这个中间Bash过程的任何想法?
注意:我正在使用C:cygwinCygwin.bat
运行Cygwin;我没有使用薄荷。
该程序是用MinGW编译的;因此它不是Cygwin程序。
MinGW程序没有真正的POSIX信号处理;只有来自ISO C的最小信号API。
它们无法响应Cygwin环境中的外部信号。MicrosoftMSVCRT.DLL
中的signal
函数与Cygwin的信号处理之间没有关系。
将信号从一个进程发送到另一个进程不是MS Windows中的概念。Cygwin在自己的领域带来了这一点,就像它带来了其他POSIX的东西一样,比如fork
和exec
,termios
控制台和其他任何东西。
MinGW中没有信号处理这样的东西。Cygwin有自己的信号处理行为,无法从Cygwin外部处理。你最好的选择是使用Cygwin的GCC编译或查看Microsoft信号。