自学Linux--sigaction function
来源:互联网 发布:linux 硬盘的dd命令 编辑:程序博客网 时间:2024/05/16 05:48
#include<signal.h>int sigaction(int sig, struct sigaction *act , struct sigaction *oact) ;struct sigaction{ void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void);}
这个函数可以:1.给一个signal安装一个handler,并且在使用sigaction修改该handler之前,不用reinstall
2.使用sigaction结构,该结构包含handler,其中可以指定2个handler,一个是使用sigiinfo_t等参数的handler,即支持给handler更多的参数,使其可以知道自己是被什么进程,那个用户,发来的什么信号,发来该信号的具体的原因是什么,当然要像这样,得给sigaction的sa_flags设置SA_SIGINFO标记。
3.使用sigaction的sa_flags标记还可以指定系统调用被这个信号打断后,是直接返回,还是自动restart.一个典型就是,一般我们不让SIGALRM信号将被打断的系统调用restart,因为SIGALARM一般本来就是用来打断一个block的调用的。
4.为了模仿老的signal函数的作用,实现unreliable的类似signal的操作,可以通过给sa_flags设置SA_RESETHAND使handler不会自动reinstall,以及SA_NODEFER标记来使在本信号的handler内部,本信号不被自动block,当然如果你手动在sa_mask中指定要block本信号的话就可以将其block了。
5.通过使用sigaction结构中的sa_mask,可以在该handler执行的过程中,block一些信号,注意,这个mask是与我们使用sigprocmask设置的mask不同的mask,这个mask的作用范围仅限于本handler函数,而且他不会将我们用sigprocmask设置的mask取消,而仅仅是在其基础上再次将一些信号block掉,当handler结束时,系统会自动将mask恢复成以前的样子,所以这个sigaction中的sa_mask只作用本信号的handler的执行时间。
此外,系统为了避免一个signal handler的执行的时候再次被本signal打断,就自动在本handler执行之前,将本signal加入sigaction的sa_mask中,使本handler的执行过程中,不会受到本signal的嵌套打扰,单是如果本handler对应的信号的确发生了,那么该信号会在本handler执行完后执行,但只执行一次,因为只能记录一次,当然如果在这次新的执行中,又发生了这种情况,应该往复下去。下面就是一段代码,它验证了如下几点:
(1).Sigaction会使handler自动将本signal给临时block
(2).在一个handler执行过程中被临时block掉的信号也会被记录,等handler完成后会被delivery。
下例子中,child一开始就pause()等待信号来临,father给他发送SIGUSR1信号,然后father就进入1秒钟的睡眠,这是为了等child在他的handler里面进入睡眠。Child受到SIGUSR1后。立即执行handler,它会进入5秒钟的睡眠。那么可见,等father睡了1秒钟后,child还在睡眠,并且在其handler里面睡眠。此时father可以连续发送2次SIGUSR1给child,我们发现child并不响应,而是依然睡足她的剩下的时间。5秒钟睡眠结束后,child醒了,它的handler退出,系统自动将临时block的SIGUSR1 unblock,此时发现有pending的SIGUSR1,因此将他delivery给child。于是child再次进入handler,此时father已经不再发送信号了,就等着孩子结束呢。所以handler结束后,child就继续执行,退出,然后father也就退出了。#include <unistd.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <sys/wait.h>void nullhandler( int num ){ puts( "child received signal" ); puts( "child sleep 5 secs in handler..." ); sleep(5); puts( "child wake up in handler after 5 secs" );}int main(){ setbuf( stdout, NULL ); int pid = fork(); if( pid == 0 ) { //child puts("child started"); printf("%d",getpid());/* sigset_t maskset,oldset,oldset1; sigemptyset( &maskset ); sigaddset( &maskset, SIGUSR1 ); sigprocmask( SIG_BLOCK, &maskset, &oldset );*/ struct sigaction act, oldact; act.sa_handler = nullhandler; sigemptyset( &act.sa_mask ); if( sigaction( SIGUSR1, &act,0 ) < 0 ) { puts(" child install handler failed"); return -1; } /* puts("child went to sleep ..."); sleep(5); puts("child wake up..."); sigset_t pendset; if( sigpending( &pendset ) < 0 ) { puts("get pending signal failed"); return -1; } if( sigismember( &pendset, SIGUSR1 ) ) puts("SIGUSR1 is pending signal"); else puts("SIGUSR1 is pending signal"); puts("child is unblocking signal"); if( sigprocmask(SIG_UNBLOCK, &maskset, &oldset1 ) < 0 ) puts("unblock signal failed"); else puts("unblock signal success"); */ puts("child waiting for signal..."); /*pause函数只是简单地将进程挂起,直至进程接受到一个terminal信号,或是一个信号函数将信号捕捉,并进行调用。*/ pause(); puts("child returnd from signal handler"); puts("child is quiting"); exit(0); } sleep(1); puts( " father send SIGUSR1 once" ); int ret = kill( pid, SIGUSR1 ); puts("father sleep 1 sec to ensure child is now in signal handler"); sleep(1); puts( " father send SIGUSR1 twice" ); ret = kill( pid, SIGUSR1 ); puts( " father send SIGUSR1 third times" ); ret = kill( pid, SIGUSR1 ); /*等待子进程的结束。*/ waitpid( pid, 0, 0); puts("father is quiting"); return 0;}
输出结果:
child started
child waiting for signal...
father send SIGUSR1 once
father sleep 1 sec to ensure child is now in signal handler
child received signal
child sleep 5 secs in handler...
father send SIGUSR1 twice
father send SIGUSR1 third times
child wake up in handler after 5 secs
child received signal
child sleep 5 secs in handler...
child wake up in handler after 5 secs
child returnd from signal handler
child is quiting
father is quiting感谢大牛文章的指导:http://blog.chinaunix.net/space.php?uid=12072359&do=blog&id=2961076
- 自学Linux--sigaction function
- linux sigaction
- Linux Signal (7): sigaction
- Linux Signal (7): sigaction
- Linux Signal (4): sigaction
- linux sigaction结构分析
- linux sigaction and sigqueue
- linux信号 sigaction 进阶
- linux进程---sigaction 函数
- Linux sigaction信号机制积累
- linux c ---signal 和sigaction
- linux下的struct sigaction
- LINUX信号- sigaction 函数-10.14
- Linux进程学习-sigaction()函数
- Linux下alarm,sigaction,pause
- Linux 进程------sigaction 函数解析
- sigaction()
- sigaction
- Oracle 数据库监听配置
- QQ的HTTP接口协议探究
- linux合并pdf文档[ghostscript]
- ural 1084 Goat in the Garden
- R2链接池1.7版与proxool比较
- 自学Linux--sigaction function
- 2012技术方向上的期望
- 程序员,如何远离你的电脑
- 快递服务与计算机网络的关系
- 技术随笔(密码保存,MSMQ)
- ZIP压缩与解压
- 除法变加减和移位的实现:试探减法
- IBM大型主机学习总结(二)
- FTP服务器原理