IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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函数的定义:

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 
struct sigaction { 
	void (*sa_handler)(int); 
	void (*sa_sigaction)(int, siginfo_t *, void *); 
	sigset_t sa_mask;
	int sa_flags; 
	void (*sa_restorer)(void); 
};

上面给出的sigaction结构体的定义并非严格意义上的定义,即结构体必须要有上述的成员变量,但成员变量的具体顺序取决于实现。

sa_mask

顾名思义,sa_mask就是信号处理函数执行期间的屏蔽信号集。

前文介绍bsd_signal的时候曾提到,为SIGINT安装处理函数时,内核会自动将SIGINT添加入屏蔽信号集,在SIGINT信号处理函数执行期间,SIGINT信号不会被递送给进程。但是,也仅仅是SIGINT,如果执行SIGINT信号处理函数期间,需要屏蔽SIGHUP、SIGUSR1等其他信号,那bsd_signal函数就爱莫能助了

这个屏蔽其他信号的需求对sigaction函数而言,根本就不是问题,只需如下代码即可做到:

struct sigaction sa; 
sa.sa_mask = SIGHUP|SIGUSR1|SIGINT;
  • 需要特别指出的是,并不是所有的信号都能被屏蔽

对于**SIGKILL和SIGSTOP,**不可以为它们安装信号处理函数,也不能屏蔽掉这些信号

原因是,系统总要控制某些进程,如果进程可以自行设计所有信号的处理函数,那么操作系统可能无法控制这些进程。换言之,操作系统是终极boss,需要杀死某些进程的时候,要能够做到,SIGKILL和SIGSTOP不能被屏蔽,就是为了防止出现进程无法无天而操作系统徒叹奈何的困境。

注意:

SIGKILL和SIGSTOP也不是万能的。如果进程处于TASK_UNINTERRUPTIBLE的状态,进程就不会处理信号。如果进程失控,长期处于该状态,SIGKILL也无法杀死该进程。详情可以回顾第5章。

sa_flag

若通过sigaction强行给SIGKILL或SIGSTOP注册信号处理函数,则会返回-1,并置errno为EINVAL。

  • 在sigaction函数接口中,比较有意思的是sa_flags。
  • sigaction函数之所以可以提供更精确的控制,大部分都是该参数的功劳。

下面简要介绍一下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及发送的额外信息。

来看下面的例子:

 void  sig_handler(int signo, siginfo_t *info, void *context)
{
	printf("\nget signal : %d\n", signo);
	printf("signal number is %d\n", info->si_signo);
	printf("pid=%d\n", info->si_pid);
	printf("sigval = %d\n", info->si_value.sival_int);
}

int main(int argc, char *argv[])
{
	struct sigaction new_act;
	sigemptyset(&new_act.sa_mask);

	new_act.sa_sigaction = sig_handler;
	new_act.sa_flags    |= SA_SIGINFO | SA_RESTART;
        if (sigaction(36, &new_act, NULL) == -1)
	{
		perror("sigaction");
		exit(-1);
	}
	while(1)
		pause();
	printf("Done\n");
	exit(0);
}

这个例子比较简单,为36号信号注册了信号处理函数

因为sa_flags带上了SA_SIGINFO标志位,所以必须使用三参数的信号处理函数。

void sig_handler(int signo,siginfo_t *info,void *context)

本例中的信号处理函数中,

  1. info->si_pid记录着信号发送者的PID
  2. info->si_value.sival_int是信号发送进程时额外发送的int值
  3. 发送进程和接收进程约定好,发送者使用sigqueue发送信号,同时带上int型的额外信息,接收进程就能获得发送进程的PID及int型的额外信息。

如果调用sigaction函数时,sa_flags带了SIGINFO标志位,那么进程可以获得哪些信息?

6.8.3小节介绍sigqueue函数时,会展开讲述。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:59:27  更:2022-03-24 01:00:33 
 
开发: 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-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码