| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 6.7 信号的安装 -> 正文阅读 |
|
[系统运维]6.7 信号的安装 |
6.7 信号的安装前面讲了传统信号的很多弊端,讲了signal的兼容性问题,有问题就会有解决方案。 对此,Linux提供了新的信号安装方法:sigaction函数。 和signal函数相比,这个函数的优点在于语义明确,可以提供更精确的控制。 先来看一下sigaction函数的定义:
上面给出的sigaction结构体的定义并非严格意义上的定义,即结构体必须要有上述的成员变量,但成员变量的具体顺序取决于实现。 sa_mask顾名思义,sa_mask就是信号处理函数执行期间的屏蔽信号集。 前文介绍bsd_signal的时候曾提到,为SIGINT安装处理函数时,内核会自动将SIGINT添加入屏蔽信号集,在SIGINT信号处理函数执行期间,SIGINT信号不会被递送给进程。但是,也仅仅是SIGINT,如果执行SIGINT信号处理函数期间,需要屏蔽SIGHUP、SIGUSR1等其他信号,那bsd_signal函数就爱莫能助了。 这个屏蔽其他信号的需求对sigaction函数而言,根本就不是问题,只需如下代码即可做到:
对于**SIGKILL和SIGSTOP,**不可以为它们安装信号处理函数,也不能屏蔽掉这些信号。 原因是,系统总要控制某些进程,如果进程可以自行设计所有信号的处理函数,那么操作系统可能无法控制这些进程。换言之,操作系统是终极boss,需要杀死某些进程的时候,要能够做到,SIGKILL和SIGSTOP不能被屏蔽,就是为了防止出现进程无法无天而操作系统徒叹奈何的困境。 注意: SIGKILL和SIGSTOP也不是万能的。如果进程处于TASK_UNINTERRUPTIBLE的状态,进程就不会处理信号。如果进程失控,长期处于该状态,SIGKILL也无法杀死该进程。详情可以回顾第5章。 sa_flag若通过sigaction强行给SIGKILL或SIGSTOP注册信号处理函数,则会返回-1,并置errno为EINVAL。
下面简要介绍一下sa_flags的含义,其中很多标志位并不是新面孔,前面已经讨论过了。 (1)SA_NOCLDSTOP这个标志位只用于SIGCHLD信号。4.7节“等待子进程”中曾经提到过,父进程可以监测子进程的三种事件:
其中SA_NOCLDSTOP标志位是用来控制第二种和第三种事件的。 即一旦父进程为SIGCHLD信号设置了这个标志位,那么子进程停止和子进程恢复这两件事情,就无须向父进程发送SIGCHLD信号了。 (2)SA_NOCLDWAIT这个标志只用于SIGCHLD信号,它可控制上面提到的子进程终止时的行为。 如果父进程为SIGCHLD设置了SA_NOCLDWAIT标志位,那么子进程退出时,就不会进入僵尸状态,而是直接自行了断。 但是子进程还会不会向父进程发送SIGCHLD信号呢? 这取决于具体的实现。对于Linux而言,仍然会发送SIGCHLD信号。这点和上面的SA_NOCLDSTOP略有不同。 (3)SA_ONESHOT和SA_RESETHAND这两个标志位的本质是一样的,表示信号处理函数是一次性的. 信号递送出去之后,信号处理函数便恢复成默认值SIG_DFL。 (4)SA_NODEFER和SA_NOMASK这两个标志位的作用是一样的,在信号处理函数执行期间,不阻塞当前信号。 (5)SA_RESTART这个标志位表示,如果系统调用被信号中断,则不返回错误,而是自动重启系统调用。 (6)SA_SIGINFO这个标志位表示信号发送者会提供额外的信息。 这种情况下,信号处理函数应该为三参数的函数,代码如下: void handle(int, siginfo_t *, void *); 此处重点讲述一下带SA_SIGINFO标志位的信号安装方式。 本章引言中提到过,signal的本质是一种进程间的通信。 一个进程向另外一个进程发送信号,能够传递的信息,不仅仅是signo,它还可以发送更多的信息,而接收进程也能获取到发送进程的PID、UID及发送的额外信息。 来看下面的例子:
这个例子比较简单,为36号信号注册了信号处理函数。 因为sa_flags带上了SA_SIGINFO标志位,所以必须使用三参数的信号处理函数。 void sig_handler(int signo,siginfo_t *info,void *context) 本例中的信号处理函数中,
如果调用sigaction函数时,sa_flags带了SIGINFO标志位,那么进程可以获得哪些信息? 6.8.3小节介绍sigqueue函数时,会展开讲述。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 23:55:40- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |