信号处理2
#include <sys/signalfd.h> #include <signal.h> #include <unistd.h> #include <stdio.h> #include <sys/wait.h> int main(void) { sigset_t set; int fd; struct signalfd_siginfo si; int oldfd = -1; int flags = 0; pid_t pid; ssize_t s; int status; int size = sizeof(struct signalfd_siginfo); /* initiate signal set, current no signal */ sigemptyset(&set); /* add SIGCHLD to this set */ sigaddset(&set, SIGCHLD); /* this process has a signal mask, add signals in the set to mask */ /* SIG_BLOCK means, you need to take the initiative to process this SIGNAL */ sigprocmask(SIG_BLOCK, &set, NULL); fd = signalfd(oldfd, &set, flags); pid = fork(); if (pid) { while (1) { s =read(fd, &si, size); if (s == size) { printf("get signal %d, SIGCHLD is %d\n", si.ssi_signo, SIGCHLD); printf("child pid %d, signal pid %d\n", pid, si.ssi_pid); wait(&status); break; } } } else { printf("This is Child process\n"); } return 0; }
-----------------
那么现在回过头来看,设置signal和struct sigaction都是设置处理函数,并不涉及阻塞信号
而signalfd和epoll结合时,代码出现的sigprocmask,阻塞信号,就能理解为什么了
-------------------------------
- 概念一:对信号的三种处理方式
忽略 | 人为设置 |
捕捉 | 人为设置并提供处理函数 |
系统默认动作 | 很多也是忽略 |
- 概念二:信号的三种状态
发生 Generation | 事件的发生 -> 信号发生 |
到达 Delivery | 该进程的进程表中设置了该信号的标志位 |
等待 Pending |
事件发生了,到进程表中标志位设置之前的期间 注: 当信号发生时,若该进程没有运行,稍后该信号才会传递; 当信号发生时,该进程正在运行,则信号会立即被传递给进程 |
- 概念三:阻塞
- 当信号发生后,信号一直处于Pending状态,直到进程主动去处理。
- 我的理解就是和epoll结合,当你去读epoll_event,读到该信号事件,再作处理,这就是主动处理;若你不去读,该信号的发生也不会产生中断,去打扰你当前在处理的事情
- 另外,当你阻塞某信号时,该信号的处理方式不能是忽略
-------------------------------------------
这回看LINUX/UNIX系统编程手册上第20章我算是看明白什么是阻塞了。
注:
struct sigaction里,会用到sigemptyset函数,但是不会添加阻塞信号。
而signalfd里是会添加,还会调用sigprocmask。
--------------------------------------------------------
看UNIX环境高级编程第10章。
再看LINUX/UNIX系统编程手册上第20章。
---------------------------------
我还是不能理解sigprocmask这个函数,既然发生这个信号要做相应的处理,那为什么要屏蔽这个信号??
所以屏蔽是啥意思?
看到一种说法是,当发生一次这个信号,然后在做处理,在处理过程中,也就是返回前,不会再次传递该信号。
是这个意思?
-----------------------------
不是标记了很多章吗?但其实没有实操我根本就不会看进去,我一直觉得自己理解能力很可以了,但是这些知识点我串不起来,不知道他为什么要讲,现在。
-------------
当前我用过的信号处理有两种,一个是signal注册处理函数,一个是sigaction注册处理函数。
其中,sigaction注册里,结构体struct sigaction的成员sa_handler只有信号返回;成员sa_sigaction可以获取siginfo_t,该结构体保存了不少信息,用来标识引发该信号的原因
但一个更好的实现,是使用signalfd,用epoll来统一in
读取signalfd时,读取结构体struct signalfd_signinfo,该结构体包含的信息相当丰富,满足比较大的需求
参考:Linux/UNIX系统编程手册上,22.11通过文件描述符来获取信号
第20章 信号:基本概念
第21章 信号:信号处理器函数
第22章 信号:高级特性
第26章 监控子进程
主要是SIGCHLD信号
posted on 2021-05-14 17:27 toughcactus 阅读(48) 评论(0) 编辑 收藏 举报