关于主线程收不到信号的问题

在一个应用中,注册了信号的处理函数,并添加了相应的处理。

主程序中,同时也调用了msgrcv接口(工作在阻塞状态下)。程序运行在前台,当按下ctrl+c的时信号处理函数并没有收到该信号,而是msgrcv收到信号中断退出了。这样的话,信号处理函数就没有什么作用了。

针对这个问题,大家如何看,又如何处理?

阅读 5.5k
2 个回答

好问题.

"信号处理函数并没有收到该信号,而是msgrcv收到信号中断退出"
-- 不是这样的. signal handler有收到信号, 但是msgrcv 在 signal handler返回后, 不会被 自动重启.

http://linux.die.net/man/7/signal

Interruption of system calls and library functions by signal handlers

If a signal handler is invoked while a system call or library function
call is blocked
, then either:

  • the call is automatically restarted after the signal handler returns; or

  • the call fails with the error EINTR.

对于msgrcv, http://linux.die.net/man/2/msgrcv

The calling process catches a signal. In this case the system call
fails with errno set to EINTR. (msgrcv() is never automatically
restarted after being interrupted by a signal handler
, regardless of
the setting of the SA_RESTART flag when establishing a signal
handler.)

所以你需要把msgrcv 放入循环:

do{
    result = msgrcv(id, (void *) &msg, sizeof(msg.text),
         msgtyp, MSG_NOERROR);
} while(result == -1 && errno == EINTR);

ctrl+c发送信号
我个人认为,信号处理方式应该不是按照正常的消息处理的,应该属于软中断的方式。
如果单纯的想处理ctrl+c的消息的话,使用signal函数就是了,而且根据该还是的调用方式,将处理函数与信号绑定,以回调的方式进行调用,那么信号的产生方式大概就是软中断。所以使用阻塞态也不一定可以捕获到。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进