持久的信号处理

Mat*_*att 1 c linux signals pthreads

我正在尝试编写一个信号处理程序来捕获任意数量的连续SIGINT信号并阻止程序退出.该程序是一个简单的文件服务器.处理程序设置一个全局标志,导致while循环接受新连接结束,对pthread_exit()的调用确保main允许当前连接在退出之前完成.当我点击ctrl-C一次但第二次立即退出程序时,这一切都像发条一样.

我首先尝试使用signal():

signal(SIGINT, catch_sigint);

...

static void catch_sigint(int signo)
{
    ...
    signal(SIGINT, catch_sigint);
}
Run Code Online (Sandbox Code Playgroud)

我也尝试使用sigaction:

struct sigaction sigint_handler;
sigint_handler.sa_handler = catch_sigint;
sigemptyset(&sigint_handler.sa_mask);
sigint_handler.sa_flags = 0;
sigaction(SIGINT, &sigint_handler, NULL);
Run Code Online (Sandbox Code Playgroud)

不确定如何"重新安装"这个我只是在处理程序中复制此代码类似于使用signal()方法的处理程序.

这些都不像我预期的那样有效.


附加信息:

该程序是一个简单的文件服务器.它接收来自客户端的请求,该请求只是一个由请求的文件名组成的字符串.它利用pthreads,以便可以同时进行传输.收到SIGINT后,我希望服务器退出while循环并等待所有当前传输完成然后关闭.原样,无论我如何编码信号处理程序,第二个SIGINT立即终止程序.

int serverStop = 0;

...

int main()
{
   /* set up the server -- socket(), bind() etc. */

   struct sigaction sigint_hadler;
   sigint_handler.sa_handler = catch_sigint;
   sigint_handler.sa_flags = 0;
   sigemptyset(&sigint_handler.sa_mask);
   sigaction(SIGINT, &sigint_handler, NULL);

   /* signal(SIGINT, catch_sigint); */

   while(serverStop == 0)
   {
      /* accept new connections and pthread_create() for each */
   }
   pthread_exit(NULL);
}

...

static void catch_sigint(int signo)
{
   serverStop = 1;

   /* signal(SIGINT, catch_sigint) */
}
Run Code Online (Sandbox Code Playgroud)

我不认为任何其他代码可能是相关的,但可以随意要求详细说明

Emp*_*ian 6

在Linux上,您不必使用任何一个signal(默认情况下实现BSD语义)或重新安装信号处理程序sigaction.

当我按下ctrl-C一次,但第二次立即退出程序.

这不是因为你的处理程序被重置,但可能是因为你的信号处理程序正在做一些它不应该做的事情.

以下是我将如何调试此问题:在GDB下运行程序

(gdb) catch syscall exit
(gdb) catch syscall exit_group
(gdb) run
Run Code Online (Sandbox Code Playgroud)

现在等待程序开始工作,然后点击Control-C.这会给你(gdb)提示.现在继续该程序,就像它已收到SIGINT:( signal SIGINT这将调用您的处理程序).再次重复'Control-C/signal SIGINT'序列.如果您在系统调用exitexit_group系统调用中停止,请查看它的来源(使用GDB where命令).

更新:

鉴于您发布的新代码,目前尚不清楚您在何处调用pthread_exit"确保主要允许当前连接在退出之前完成".由于写的,你的主线程将退出在第一控制-C循环,并继续呼吁exit这将不会等待其它线程完成.

要么你没有显示你的实际代码,要么"第二个Control-C"是一个红色的鲱鱼,你的第一个Control-C已经把你带走了(没有完成其他线程的工作).