windows下信号机制的学习

以前没有注意过这个问题, 近期在代码中看到了用到windows下的signal, MSDN, 上网查了查, 并写了测试的代码, 得出以下结论:

    1. windows下支持的信号时有限的, 在signal.h中定义, 分别是

             SIGINT      Ctrl+C中断

             SIGILL       非法指令

             SIGFPE      浮点异常

             SIGSEGV   段错误, 非法指针访问

             SIGTERM   kill发出的软件终止

             SIGBREAK Ctrl+Break中断

             SIGABRT   调用abort导致

    2. windows信号的机制~~~

             1. 表象

                 跟踪了SIGSEGV 和 SIGABRT, 发现这两个信号处理线程和程序的主线程是同一个线程

                 跟踪了SIGINT 和 SIGBREAK, 发现这两个信号处理线程和程序的主线程不是是同一个线程, 而其信号线程的优先级更高

             2. 查资料

                 看MSDN这段话"SIGINT(我觉得应该再加上SIGBREAK) is not supported for any Win32 application. when Ctrl-C interrupt occurs, win32 operating systemd generate a new thread to specifically handle that interrupt. this can cause a sigle-thread application such as one in UNIX to become multithreaded, resulting in unexpected behavior" 意思是在建议在win2应用程序中使用SIGINT和SIGBREAK信号, 因为当这两个信号发生时, OS会专门产生新的线程来处理信号~~~这将导致一个单线程程序表现出多线程程序的特点, 引发未定义行为.

              3. 看代码

                  查看了crt, 发现在调用signal(SIGINT/SIGBREAK, handlefunc)的时候, 如果signal函数发现注册是的SIGINT或者是SIGBREAK信号的话, 就会调用SetConsoleCtrlHandler函数, 把一个名为ctrlevent_capture的函数注册进console的control handler function list(每个console程序都有一个这样的队列用于处理Ctrl-C, Ctrl-Break事件, SetConsoleCtrlHandler可以把一个新的handler function压到队尾, 当事件发生时, 会从队尾开始, 产生线程[线程函数就是压入的handle function]处理事件, 直到某个handle function返回值为true, 如果都不返回true, 就会调用ExitProcess)

                  所以, 当调用signal(SIGINT/SIGBREAK, handlefunc)发生以下事件

                          1. 保存handlefunc到合适位置

                          2. SetConsoleCtrlHandler(ctrlevent_capture, true), 也就是说ctrlevent_capture函数被压入到队列尾部

                  当信号发生时发生以下事件

                          1. CreateThread(…, ctrlevent_capture, …)

                          2. 在ctrlevent_capture的内部, 会取出handlefunc, 并调用

                          3. ctrlevent_capture返回的是true~~~所以Ctrl-C处理到此为止

                  综上所述, SIGINT/SIGBREAK的确是OS新产生的线程来处理的

    3. 由于本人略看过linux低版本的代码, 所以在这里再比较一下linux和windows信号的区别

              1. 这两者完全是两码事, 不可放在同一级别讨论

              2. linux信号种类丰富, windows就几种

              3. linux信号是操作系统的一种机制, windows信号是CRT库提供的一种功能

              4. linux信号的产生和处理不是连续的, 产生SIG的地方只是置位task的sigmask~~~直到系统调用或者中断结束后, 才有可能去处理信号, 也就是信号的发生和处理是异步的

                  windows信号, 除了SIGINT/SIGBREAK, 其他信号都是类似于

                       if (注册了SIGXX)

                              调用handlerfunc

                  及发生和处理时一起的同步的

    4. 看到这些, 相信对windows信号的使用和底层实现的了解就算比较明白了, 希望对大家有帮助

posted @ 2010-04-09 07:19  ROTC  阅读(14807)  评论(0编辑  收藏  举报