鱼C论坛

 找回密码
 立即注册
查看: 1699|回复: 1

[已解决]signal 函数的使用问题。

[复制链接]
发表于 2022-1-9 13:22:17 | 显示全部楼层 |阅读模式
1鱼币
小甲鱼老师的带你学C带你飞第一季,函数快查下面的signal 函数介绍,地址为:https://fishc.com.cn/forum.php?m ... peid%26typeid%3D583

函数结束完毕后,最后有一个举例,我在Windows 10上用codeblocks测试,程序运行后按ctrl+c没有反应,程序无法终止,只能强行关闭!
我知道小甲鱼的操作是在linux下面进行的,是不是Windows不支持该操作?因为我看了windwos官方文档,上面对signal函数的原型解释为   void __cdecl *signal(int sig, int (*func)(int, int));
不知道是不是这个原因还是因为其他?请教大神帮忙!
附上小甲鱼老师的举例源代码:

#include <stdio.h>
#include <signal.h>

void signal_handler_fun(int signal_num)
{
        printf("捕获信号:%d\n", signal_num);
}

int main(void)
{
        signal(SIGINT, signal_handler_fun);

        while (1)
        {
                ;
        }

        return 0;
}
最佳答案
2022-1-9 13:22:18

vs里面的
  1. /***
  2. *_PHNDLR signal(signum, sigact) - Define a signal handler
  3. *
  4. *Purpose:
  5. *       The signal routine allows the user to define what action should
  6. *       be taken when various signals occur. The Win32/Dosx32 implementation
  7. *       supports seven signals, divided up into three general groups
  8. *
  9. *       1. Signals corresponding to OS exceptions. These are:
  10. *                       SIGFPE
  11. *                       SIGILL
  12. *                       SIGSEGV
  13. *          Signal actions for these signals are installed by altering the
  14. *          XcptAction and SigAction fields for the appropriate entry in the
  15. *          exception-action table (XcptActTab[]).
  16. *
  17. *       2. Signals corresponding to ^C and ^Break. These are:
  18. *                       SIGINT
  19. *                       SIGBREAK
  20. *          Signal actions for these signals are installed by altering the
  21. *          _ctrlc_action and _ctrlbreak_action variables.
  22. *
  23. *       3. Signals which are implemented only in the runtime. That is, they
  24. *          occur only as the result of a call to raise().
  25. *                       SIGABRT
  26. *                       SIGTERM
  27. *
  28. *
  29. *Entry:
  30. *       int signum      signal type. recognized signal types are:
  31. *
  32. *                       SIGABRT         (ANSI)
  33. *                       SIGBREAK
  34. *                       SIGFPE          (ANSI)
  35. *                       SIGILL          (ANSI)
  36. *                       SIGINT          (ANSI)
  37. *                       SIGSEGV         (ANSI)
  38. *                       SIGTERM         (ANSI)
  39. *                       SIGABRT_COMPAT
  40. *
  41. *       _PHNDLR sigact  signal handling function or action code. the action
  42. *                       codes are:
  43. *
  44. *                       SIG_DFL - take the default action, whatever that may
  45. *                       be, upon receipt of this type type of signal.
  46. *
  47. *                       SIG_DIE - *** ILLEGAL ***
  48. *                       special code used in the XcptAction field of an
  49. *                       XcptActTab[] entry to indicate that the runtime is
  50. *                       to terminate the process upon receipt of the exception.
  51. *                       not accepted as a value for sigact.
  52. *
  53. *                       SIG_IGN - ignore this type of signal
  54. *
  55. *                       [function address] - transfer control to this address
  56. *                       when a signal of this type occurs.
  57. *
  58. *Exit:
  59. *       Good return:
  60. *       Signal returns the previous value of the signal handling function
  61. *       (e.g., SIG_DFL, SIG_IGN, etc., or [function address]). This value is
  62. *       returned in DX:AX.
  63. *
  64. *       Error return:
  65. *       Signal returns -1 and errno is set to EINVAL. The error return is
  66. *       generally taken if the user submits bogus input values.
  67. *
  68. *Exceptions:
  69. *       None.
  70. *
  71. *******************************************************************************/

  72. _PHNDLR __cdecl signal(
  73.         int signum,
  74.         _PHNDLR sigact
  75.         )
  76. {
  77.         struct _XCPT_ACTION *pxcptact;
  78.         _PHNDLR oldsigact;
  79.         int Error=0;
  80.         _ptiddata ptd;
  81.         BOOL SetConsoleCtrlError = FALSE;

  82.         /*
  83.          * Check for values of sigact supported on other platforms but not
  84.          * on this one. Also, make sure sigact is not SIG_DIE
  85.          */
  86.         if ( (sigact == SIG_ACK) || (sigact == SIG_SGE) )
  87.                 goto sigreterror;

  88.         /*
  89.          * Take care of all signals which do not correspond to exceptions
  90.          * in the host OS. Those are:
  91.          *
  92.          *                      SIGINT
  93.          *                      SIGBREAK
  94.          *                      SIGABRT
  95.          *                      SIGTERM
  96.          *
  97.          */
  98.         if ( (signum == SIGINT) || (signum == SIGBREAK) || (signum == SIGABRT)
  99.             || (signum == SIGABRT_COMPAT) || (signum == SIGTERM) ) {

  100.                 _mlock( _SIGNAL_LOCK );
  101.                 __try {

  102.                 /*
  103.                  * if SIGINT or SIGBREAK, make sure the handler is installed
  104.                  * to capture ^C and ^Break events.
  105.                  */
  106.                 if ( ((signum == SIGINT) || (signum == SIGBREAK)) &&
  107.                     !ConsoleCtrlHandler_Installed )
  108.                                 {
  109.                         if ( SetConsoleCtrlHandler(ctrlevent_capture, TRUE)
  110.                             == TRUE )
  111.                                                 {
  112.                                 ConsoleCtrlHandler_Installed = TRUE;
  113.                                                 }
  114.                         else
  115.                                                 {
  116.                                 _doserrno = GetLastError();
  117.                                                                 SetConsoleCtrlError=TRUE;
  118.                         }
  119.                                 }

  120.                 switch (signum) {

  121.                         case SIGINT:
  122.                                 oldsigact = (_PHNDLR) DecodePointer(ctrlc_action);
  123.                                 if(sigact!=SIG_GET)
  124.                                 {
  125.                                     ctrlc_action = (_PHNDLR) EncodePointer(sigact);
  126.                                 }
  127.                                 break;

  128.                         case SIGBREAK:
  129.                                 oldsigact = (_PHNDLR) DecodePointer(ctrlbreak_action);
  130.                                 if(sigact!=SIG_GET)
  131.                                 {
  132.                                     ctrlbreak_action = (_PHNDLR) EncodePointer(sigact);
  133.                                 }
  134.                                 break;

  135.                         case SIGABRT:
  136.                         case SIGABRT_COMPAT:
  137.                                 oldsigact = (_PHNDLR) DecodePointer(abort_action);
  138.                                 if(sigact!=SIG_GET)
  139.                                 {
  140.                                     abort_action = (_PHNDLR) EncodePointer(sigact);
  141.                                 }
  142.                                 break;

  143.                         case SIGTERM:
  144.                                 oldsigact = (_PHNDLR) DecodePointer(term_action);
  145.                                 if(sigact!=SIG_GET)
  146.                                 {
  147.                                     term_action = (_PHNDLR) EncodePointer(sigact);
  148.                                 }
  149.                                 break;
  150.                 }

  151.                 }
  152.                 __finally {
  153.                         _munlock( _SIGNAL_LOCK );
  154.                 }

  155.                 if (SetConsoleCtrlError) {
  156.                     goto sigreterror;
  157.                 }
  158.                 goto sigretok;
  159.         }

  160.         /*
  161.          * If we reach here, signum is supposed to be one the signals which
  162.          * correspond to exceptions in the host OS. Those are:
  163.          *
  164.          *                      SIGFPE
  165.          *                      SIGILL
  166.          *                      SIGSEGV
  167.          */

  168.         /*
  169.          * Make sure signum is one of the remaining supported signals.
  170.          */
  171.         if ( (signum != SIGFPE) && (signum != SIGILL) && (signum != SIGSEGV) )
  172.                 goto sigreterror;


  173.         /*
  174.          * Fetch the tid data table entry for this thread
  175.          */
  176.         ptd = _getptd_noexit();
  177.         if (!ptd)
  178.             goto sigreterror;

  179.         /*
  180.          * Check that there a per-thread instance of the exception-action
  181.          * table for this thread. if there isn't, create one.
  182.          */
  183.         if ( ptd->_pxcptacttab == _XcptActTab )
  184.                 /*
  185.                  * allocate space for an exception-action table
  186.                  */
  187.                 if ( (ptd->_pxcptacttab = _malloc_crt(_XcptActTabSize)) != NULL )
  188.                         /*
  189.                          * initialize the table by copying over the contents
  190.                          * of _XcptActTab[]
  191.                          */
  192.                         (void) memcpy(ptd->_pxcptacttab, _XcptActTab,
  193.                             _XcptActTabSize);
  194.                 else
  195.                         /*
  196.                          * cannot create exception-action table, return
  197.                          * error to caller
  198.                          */
  199.                         goto sigreterror;

  200.         /*
  201.          * look up the proper entry in the exception-action table. note that
  202.          * if several exceptions are mapped to the same signal, this returns
  203.          * the pointer to first such entry in the exception action table. it
  204.          * is assumed that the other entries immediately follow this one.
  205.          */
  206.         if ( (pxcptact = siglookup(signum, ptd->_pxcptacttab)) == NULL )
  207.                 goto sigreterror;

  208.         /*
  209.          * SIGSEGV, SIGILL and SIGFPE all have more than one exception mapped
  210.          * to them. the code below depends on the exceptions corresponding to
  211.          * the same signal being grouped together in the exception-action
  212.          * table.
  213.          */

  214.         /*
  215.          * store old signal action code for return value
  216.          */
  217.         oldsigact = pxcptact->XcptAction;

  218.         if(sigact!=SIG_GET)
  219.         {
  220.             /*
  221.             * loop through all entries corresponding to the
  222.             * given signal and update the SigAction and XcptAction
  223.             * fields as appropriate
  224.             */

  225.             while ( pxcptact->SigNum == signum ) {
  226.                     /*
  227.                     * take care of the SIG_IGN and SIG_DFL action
  228.                     * codes
  229.                     */
  230.                     pxcptact->XcptAction = sigact;

  231.                     /*
  232.                     * make sure we don't run off the end of the table
  233.                     */
  234.                     if ( ++pxcptact >= ((struct _XCPT_ACTION *)(ptd->_pxcptacttab)
  235.                                        + _XcptActTabCount) )
  236.                         break;
  237.             }
  238.         }

  239. sigretok:
  240.         return(oldsigact);

  241. sigreterror:
  242.         switch(signum)
  243.         {
  244.         case _SIGHUP_IGNORE:
  245.         case _SIGQUIT_IGNORE:
  246.         case _SIGPIPE_IGNORE:
  247.         case _SIGIOINT_IGNORE:
  248.         case _SIGSTOP_IGNORE:
  249.             return SIG_ERR;
  250.         default:
  251.             _VALIDATE_RETURN(("Invalid signal or error", 0), EINVAL, SIG_ERR);
  252.             /* should never happen, but compiler can't tell */
  253.             return SIG_ERR;
  254.         }
  255. }
复制代码

最佳答案

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-1-9 13:22:18 | 显示全部楼层    本楼为最佳答案   

vs里面的
  1. /***
  2. *_PHNDLR signal(signum, sigact) - Define a signal handler
  3. *
  4. *Purpose:
  5. *       The signal routine allows the user to define what action should
  6. *       be taken when various signals occur. The Win32/Dosx32 implementation
  7. *       supports seven signals, divided up into three general groups
  8. *
  9. *       1. Signals corresponding to OS exceptions. These are:
  10. *                       SIGFPE
  11. *                       SIGILL
  12. *                       SIGSEGV
  13. *          Signal actions for these signals are installed by altering the
  14. *          XcptAction and SigAction fields for the appropriate entry in the
  15. *          exception-action table (XcptActTab[]).
  16. *
  17. *       2. Signals corresponding to ^C and ^Break. These are:
  18. *                       SIGINT
  19. *                       SIGBREAK
  20. *          Signal actions for these signals are installed by altering the
  21. *          _ctrlc_action and _ctrlbreak_action variables.
  22. *
  23. *       3. Signals which are implemented only in the runtime. That is, they
  24. *          occur only as the result of a call to raise().
  25. *                       SIGABRT
  26. *                       SIGTERM
  27. *
  28. *
  29. *Entry:
  30. *       int signum      signal type. recognized signal types are:
  31. *
  32. *                       SIGABRT         (ANSI)
  33. *                       SIGBREAK
  34. *                       SIGFPE          (ANSI)
  35. *                       SIGILL          (ANSI)
  36. *                       SIGINT          (ANSI)
  37. *                       SIGSEGV         (ANSI)
  38. *                       SIGTERM         (ANSI)
  39. *                       SIGABRT_COMPAT
  40. *
  41. *       _PHNDLR sigact  signal handling function or action code. the action
  42. *                       codes are:
  43. *
  44. *                       SIG_DFL - take the default action, whatever that may
  45. *                       be, upon receipt of this type type of signal.
  46. *
  47. *                       SIG_DIE - *** ILLEGAL ***
  48. *                       special code used in the XcptAction field of an
  49. *                       XcptActTab[] entry to indicate that the runtime is
  50. *                       to terminate the process upon receipt of the exception.
  51. *                       not accepted as a value for sigact.
  52. *
  53. *                       SIG_IGN - ignore this type of signal
  54. *
  55. *                       [function address] - transfer control to this address
  56. *                       when a signal of this type occurs.
  57. *
  58. *Exit:
  59. *       Good return:
  60. *       Signal returns the previous value of the signal handling function
  61. *       (e.g., SIG_DFL, SIG_IGN, etc., or [function address]). This value is
  62. *       returned in DX:AX.
  63. *
  64. *       Error return:
  65. *       Signal returns -1 and errno is set to EINVAL. The error return is
  66. *       generally taken if the user submits bogus input values.
  67. *
  68. *Exceptions:
  69. *       None.
  70. *
  71. *******************************************************************************/

  72. _PHNDLR __cdecl signal(
  73.         int signum,
  74.         _PHNDLR sigact
  75.         )
  76. {
  77.         struct _XCPT_ACTION *pxcptact;
  78.         _PHNDLR oldsigact;
  79.         int Error=0;
  80.         _ptiddata ptd;
  81.         BOOL SetConsoleCtrlError = FALSE;

  82.         /*
  83.          * Check for values of sigact supported on other platforms but not
  84.          * on this one. Also, make sure sigact is not SIG_DIE
  85.          */
  86.         if ( (sigact == SIG_ACK) || (sigact == SIG_SGE) )
  87.                 goto sigreterror;

  88.         /*
  89.          * Take care of all signals which do not correspond to exceptions
  90.          * in the host OS. Those are:
  91.          *
  92.          *                      SIGINT
  93.          *                      SIGBREAK
  94.          *                      SIGABRT
  95.          *                      SIGTERM
  96.          *
  97.          */
  98.         if ( (signum == SIGINT) || (signum == SIGBREAK) || (signum == SIGABRT)
  99.             || (signum == SIGABRT_COMPAT) || (signum == SIGTERM) ) {

  100.                 _mlock( _SIGNAL_LOCK );
  101.                 __try {

  102.                 /*
  103.                  * if SIGINT or SIGBREAK, make sure the handler is installed
  104.                  * to capture ^C and ^Break events.
  105.                  */
  106.                 if ( ((signum == SIGINT) || (signum == SIGBREAK)) &&
  107.                     !ConsoleCtrlHandler_Installed )
  108.                                 {
  109.                         if ( SetConsoleCtrlHandler(ctrlevent_capture, TRUE)
  110.                             == TRUE )
  111.                                                 {
  112.                                 ConsoleCtrlHandler_Installed = TRUE;
  113.                                                 }
  114.                         else
  115.                                                 {
  116.                                 _doserrno = GetLastError();
  117.                                                                 SetConsoleCtrlError=TRUE;
  118.                         }
  119.                                 }

  120.                 switch (signum) {

  121.                         case SIGINT:
  122.                                 oldsigact = (_PHNDLR) DecodePointer(ctrlc_action);
  123.                                 if(sigact!=SIG_GET)
  124.                                 {
  125.                                     ctrlc_action = (_PHNDLR) EncodePointer(sigact);
  126.                                 }
  127.                                 break;

  128.                         case SIGBREAK:
  129.                                 oldsigact = (_PHNDLR) DecodePointer(ctrlbreak_action);
  130.                                 if(sigact!=SIG_GET)
  131.                                 {
  132.                                     ctrlbreak_action = (_PHNDLR) EncodePointer(sigact);
  133.                                 }
  134.                                 break;

  135.                         case SIGABRT:
  136.                         case SIGABRT_COMPAT:
  137.                                 oldsigact = (_PHNDLR) DecodePointer(abort_action);
  138.                                 if(sigact!=SIG_GET)
  139.                                 {
  140.                                     abort_action = (_PHNDLR) EncodePointer(sigact);
  141.                                 }
  142.                                 break;

  143.                         case SIGTERM:
  144.                                 oldsigact = (_PHNDLR) DecodePointer(term_action);
  145.                                 if(sigact!=SIG_GET)
  146.                                 {
  147.                                     term_action = (_PHNDLR) EncodePointer(sigact);
  148.                                 }
  149.                                 break;
  150.                 }

  151.                 }
  152.                 __finally {
  153.                         _munlock( _SIGNAL_LOCK );
  154.                 }

  155.                 if (SetConsoleCtrlError) {
  156.                     goto sigreterror;
  157.                 }
  158.                 goto sigretok;
  159.         }

  160.         /*
  161.          * If we reach here, signum is supposed to be one the signals which
  162.          * correspond to exceptions in the host OS. Those are:
  163.          *
  164.          *                      SIGFPE
  165.          *                      SIGILL
  166.          *                      SIGSEGV
  167.          */

  168.         /*
  169.          * Make sure signum is one of the remaining supported signals.
  170.          */
  171.         if ( (signum != SIGFPE) && (signum != SIGILL) && (signum != SIGSEGV) )
  172.                 goto sigreterror;


  173.         /*
  174.          * Fetch the tid data table entry for this thread
  175.          */
  176.         ptd = _getptd_noexit();
  177.         if (!ptd)
  178.             goto sigreterror;

  179.         /*
  180.          * Check that there a per-thread instance of the exception-action
  181.          * table for this thread. if there isn't, create one.
  182.          */
  183.         if ( ptd->_pxcptacttab == _XcptActTab )
  184.                 /*
  185.                  * allocate space for an exception-action table
  186.                  */
  187.                 if ( (ptd->_pxcptacttab = _malloc_crt(_XcptActTabSize)) != NULL )
  188.                         /*
  189.                          * initialize the table by copying over the contents
  190.                          * of _XcptActTab[]
  191.                          */
  192.                         (void) memcpy(ptd->_pxcptacttab, _XcptActTab,
  193.                             _XcptActTabSize);
  194.                 else
  195.                         /*
  196.                          * cannot create exception-action table, return
  197.                          * error to caller
  198.                          */
  199.                         goto sigreterror;

  200.         /*
  201.          * look up the proper entry in the exception-action table. note that
  202.          * if several exceptions are mapped to the same signal, this returns
  203.          * the pointer to first such entry in the exception action table. it
  204.          * is assumed that the other entries immediately follow this one.
  205.          */
  206.         if ( (pxcptact = siglookup(signum, ptd->_pxcptacttab)) == NULL )
  207.                 goto sigreterror;

  208.         /*
  209.          * SIGSEGV, SIGILL and SIGFPE all have more than one exception mapped
  210.          * to them. the code below depends on the exceptions corresponding to
  211.          * the same signal being grouped together in the exception-action
  212.          * table.
  213.          */

  214.         /*
  215.          * store old signal action code for return value
  216.          */
  217.         oldsigact = pxcptact->XcptAction;

  218.         if(sigact!=SIG_GET)
  219.         {
  220.             /*
  221.             * loop through all entries corresponding to the
  222.             * given signal and update the SigAction and XcptAction
  223.             * fields as appropriate
  224.             */

  225.             while ( pxcptact->SigNum == signum ) {
  226.                     /*
  227.                     * take care of the SIG_IGN and SIG_DFL action
  228.                     * codes
  229.                     */
  230.                     pxcptact->XcptAction = sigact;

  231.                     /*
  232.                     * make sure we don't run off the end of the table
  233.                     */
  234.                     if ( ++pxcptact >= ((struct _XCPT_ACTION *)(ptd->_pxcptacttab)
  235.                                        + _XcptActTabCount) )
  236.                         break;
  237.             }
  238.         }

  239. sigretok:
  240.         return(oldsigact);

  241. sigreterror:
  242.         switch(signum)
  243.         {
  244.         case _SIGHUP_IGNORE:
  245.         case _SIGQUIT_IGNORE:
  246.         case _SIGPIPE_IGNORE:
  247.         case _SIGIOINT_IGNORE:
  248.         case _SIGSTOP_IGNORE:
  249.             return SIG_ERR;
  250.         default:
  251.             _VALIDATE_RETURN(("Invalid signal or error", 0), EINVAL, SIG_ERR);
  252.             /* should never happen, but compiler can't tell */
  253.             return SIG_ERR;
  254.         }
  255. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-25 02:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表