导航

信号处理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编辑  收藏  举报