忽略 C 上的信号
Ignoring a signal on C
这不是代码问题,而是理论问题。
我之前有过这段代码:
void handler(int signal){
printf("Handler called\n");
}
struct sigaction act;
act.sa_handler = &handler;
act.sa_flags = 0;
if (sigaction(SIGINT, &act, NULL) < 0){
exit(1);
}
if (sigaction(SIGQUIT, &act, NULL) < 0){
exit(1);
}
当我按下 ctrl + C
时,正在调用处理程序,但程序仍然退出。
现在,出于好奇,我尝试将标志更改为 SA_RESTART
。现在不退出了。
为什么?
SA_RESTART
导致 EINTR
可中断系统调用(例如,read
)在传递已处理信号后重新启动。
所以如果你有:
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void handler(int signal)
{
printf("Handler called\n");
}
int main()
{
struct sigaction act;
act.sa_handler = &handler;
act.sa_flags = 0;
if (sigaction(SIGINT, &act, NULL) < 0){ exit(1); }
char ch; ssize_t nr;
nr=read(0,&ch,1);
}
然后使用 SA_RESTART
就好像 nr=read(0,&ch,1);
行已被替换为
while(0>(nr=read(0,&ch,1)) && errno==EINTR){}`
请注意,您应该只调用信号处理程序中的异步信号安全函数。处理程序中的 printf
通常是未定义行为的秘诀,但在这种特殊情况下,您只中断本身是异步信号安全的代码 (read
),这是相当安全的,尽管POSIX 没有明确批准它 (AFAIK)。
这不是代码问题,而是理论问题。
我之前有过这段代码:
void handler(int signal){
printf("Handler called\n");
}
struct sigaction act;
act.sa_handler = &handler;
act.sa_flags = 0;
if (sigaction(SIGINT, &act, NULL) < 0){
exit(1);
}
if (sigaction(SIGQUIT, &act, NULL) < 0){
exit(1);
}
当我按下 ctrl + C
时,正在调用处理程序,但程序仍然退出。
现在,出于好奇,我尝试将标志更改为 SA_RESTART
。现在不退出了。
为什么?
SA_RESTART
导致 EINTR
可中断系统调用(例如,read
)在传递已处理信号后重新启动。
所以如果你有:
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void handler(int signal)
{
printf("Handler called\n");
}
int main()
{
struct sigaction act;
act.sa_handler = &handler;
act.sa_flags = 0;
if (sigaction(SIGINT, &act, NULL) < 0){ exit(1); }
char ch; ssize_t nr;
nr=read(0,&ch,1);
}
然后使用 SA_RESTART
就好像 nr=read(0,&ch,1);
行已被替换为
while(0>(nr=read(0,&ch,1)) && errno==EINTR){}`
请注意,您应该只调用信号处理程序中的异步信号安全函数。处理程序中的 printf
通常是未定义行为的秘诀,但在这种特殊情况下,您只中断本身是异步信号安全的代码 (read
),这是相当安全的,尽管POSIX 没有明确批准它 (AFAIK)。