SA_RESTART到底有什么用?书上说是重启系统调用。。。不懂..怎么重启
解决时间 2021-03-02 22:14
- 提问者网友:像風在裏
- 2021-03-02 13:42
#include
#include
#define INPUTLEN 100
main()
{
struct sigaction newhandler;
sigset_t blocked;
void inthandler();
char x[INPUTLEN];
newhandler.sa_handler = inthandler;
newhandler.sa_flags = SA_RESETHAND | SA_RESTART;
sigemptyset(&blocked);
sigaddset(&blocked, SIGQUIT);
newhandler.sa_mask = blocked;
if ( sigaction(SIGINT, &newhandler, NULL) == -1 )
perror("sigaction");
else
while( 1 ){
fgets(x, INPUTLEN, stdin);
printf("input: %s", x);
}
}
void inthandler(int s)
{
printf("Called with signal %d\n", s);
sleep(s);
printf("done handling signal %d\n", s);
}
======
这个程序连续输入2个ctrl+c为什么就会推出,程序具体的执行流程是什么样的?
第一个ctrl+c信号被inthandler函数处理正在printf输出时,再输入个ctrl+c信号,这时是怎么处理的..
谢谢。。
汗,我没财富值...
最佳答案
- 五星知识达人网友:蓝房子
- 2021-03-02 14:30
我认为函数或进程的运行最终都回归结尾系统调用,(呵呵,非官方,自己理解)
那么 “进程正在执行某个系统调用,那么在该系统调用返回前信号是不会被递送的”,就是说大多数进程在运行期间是阻塞信号的,系统调用完再处理,
但是(以下引用APUE):如果在进程执行一个低速系统而阻塞期间捕捉到一个信号,该系统调用被终端不再继续执行
When a system call is slow and a signal arrives while it was blocked, waiting for something, the call is aborted and returns -EINTR , so that the library function will return -1 and set errno to EINTR . Just before the system call returns, the user program's signal handler is called.
(So, what is "slow"? Mostly those calls that can block f...我认为函数或进程的运行最终都回归结尾系统调用,(呵呵,非官方,自己理解)
那么 “进程正在执行某个系统调用,那么在该系统调用返回前信号是不会被递送的”,就是说大多数进程在运行期间是阻塞信号的,系统调用完再处理,
但是(以下引用APUE):如果在进程执行一个低速系统而阻塞期间捕捉到一个信号,该系统调用被终端不再继续执行
When a system call is slow and a signal arrives while it was blocked, waiting for something, the call is aborted and returns -EINTR , so that the library function will return -1 and set errno to EINTR . Just before the system call returns, the user program's signal handler is called.
(So, what is "slow"? Mostly those calls that can block forever waiting for external events; read and write to terminal devices, but not read and write to disk devices, wait , pause .)
This means that a system call can return an error while nothing was wrong. Usually one will want to redo the system call. That can be automated by installing the signal handler using a call to sigaction with the SA_RESTART flag set. The effect is that upon an interrupt the system call is aborted, the user program's signal handler is called, and afterwards the system call is restarted from the beginning.
我们可以选择使用循环再次调用,或者设置重新启动该系统调用 (SA_RESTART),
这是是低速系统调用被信号中断的解决办法,1循环2SA——RESTART
好啦,实验代码:
#include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9
10 void int_handler (int signum)
11 {
12 printf ("int handler %d/n",signum);
13 }
14
15 int main(int argc, char **argv)
16 {
17 char buf[100];
18 ssize_t ret;
19 struct sigaction oldact;
20 struct sigaction act;
21
22 act.sa_handler = int_handler;
23 act.sa_flags=0;
24 act.sa_flags |= SA_RESTART;
25 sigemptyset(&act.sa_mask);
26 if (-1 == sigaction(SIGINT,&act,&oldact))
27 {
28 printf("sigaction failed!/n");
29 return -1;
30 }
31
32 bzero(buf,100);
33
34 ret = read(STDIN_FILENO,buf,10);
35 if (ret == -1)
36 {
37 printf ("read error %s/n", strerror(errn o));
38 }
39 printf ("read %d bytes, content is %s/n",ret,buf );
40 sleep (10);
41 return 0;
42 }
这里我们就看第二种解决办法SA—restart
运行看结果:
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
hgfd
read 5 bytes, content is hgfd
^Cint handler 2
在程序read之前不要输入,ctrl+c这样不会中断read输入后主程序就向下运行啦,这样就不在低速的系统调用即read中啦,所以再次ctrl+c结束;
下面改程序:把程序24行注释掉:结果
^Cint handler 2
read error Interrupted system call
read -1 bytes, content is
程序立即结束啦,
但我们和第一次相比也观察到很奇怪的结果
根据结果 比较,其实是第二次运行是把ctrl+c读入,而第一次就是运行啦信号处理函数,不把ctrl+c作为READ的读入,
全部回答
- 1楼网友:我住北渡口
- 2021-03-02 15:02
你好!
sdsadsa
希望对你有所帮助,望采纳。
我要举报
大家都在看
推荐资讯