【问题标题】:Signal Handling Behavior in CygwinCygwin 中的信号处理行为
【发布时间】: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 &lt;LOOP_EXE_PID&gt;,我根本看不到输出.

当我使用 any 信号和处理程序运行 kill -## &lt;LOOP_EXE_PID&gt; 时,代码就像不存在信号处理程序一样(例如,如果我 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 &lt;LOOP_EXE_PID&gt; 发挥与 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


【解决方案1】:

MinGW 中没有信号处理之类的东西。 Cygwin 有自己的信号处理行为,不能从 Cygwin 外部处理。最好的办法是使用 Cygwin 的 GCC 编译或查看 Microsoft signals

【讨论】:

    【解决方案2】:

    程序是用MinGW编译的;因此它不是 Cygwin 程序。

    MinGW 程序没有真正的 POSIX 信号处理;仅来自 ISO C 的最小信号 API。

    它们无法响应 Cygwin 环境中的外部信号。微软MSVCRT.DLL中的signal函数与Cygwin的信号处理没有关系。

    从一个进程向另一个进程发送信号不是 MS Windows 中的概念。 Cygwin 在其自己的域中实现了这一点,就像它通过控制台和其他任何方式实现其他 POSIX 内容一样,例如 forkexectermios

    【讨论】:

    • 所以你是说如果我用 Cygwin 的 gcc 编译 loop.c 我会有更大的成功机会?
    • @DenDinh 好吧,是的。那么signal其实就是cygwin1.dll中的实现,
    • 好的,我明白了。我将尝试让 loop.c 的依赖项与 Cygwin 的 gcc 一起工作,当我有结果时我会报告...
    猜你喜欢
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多