zoukankan      html  css  js  c++  java
  • Linux信号机制

    Linux信号机制

    信号机制是进程间相互传递消息的一种方法,信号全称为软中断信号,信号是进程控制的一部分。从进程的描述符PCB中,也可以看到进程关于信号处理的身影。

    /*
        35. 信号处理 
            1) signal: 指向进程的信号描述符
            2) sighand: 指向进程的信号处理程序描述符
        */
        struct signal_struct *signal;
        struct sighand_struct *sighand;
        /*
            3) blocked: 表示被阻塞信号的掩码
            4) real_blocked: 表示临时掩码
        */
        sigset_t blocked, real_blocked;
        sigset_t saved_sigmask;     
        /*
            5) pending: 存放私有挂起信号的数据结构
        */
        struct sigpending pending;
        /*
            6) sas_ss_sp: 信号处理程序备用堆栈的地址
            7) sas_ss_size: 表示堆栈的大小
        */
        unsigned long sas_ss_sp;
        size_t sas_ss_size;
        /*
            8) notifier
            设备驱动程序常用notifier指向的函数来阻塞进程的某些信号
            9) otifier_data
            指的是notifier所指向的函数可能使用的数据。
            10) otifier_mask
            标识这些信号的位掩码
        */
        int (*notifier)(void *priv);
        void *notifier_data;
        sigset_t *notifier_mask;
    

    进程之间可以通过系统调用相互发送信号;内核也可以因为某种事件向用户进程发送某种信号,通知进程发生了某种事件,但是请注意,信号只是用来通知进程发生了事件,其本身不会携带任何信息。

    可以从如下几个方面来理解信号:1、进程如何存储信号。2、进程如何感知信号。3、进程如何处理信号。

    1.进程如何存储信号

    在进程描述符中有一个未决(pending)信号集合(所谓的未决是指信号产生,但还未对信号做出处理决定),信号的注册其实就是指在这个未决(pending)信号集中标记对应的信号数值二进制位为1.

    上面代码列出了进程中关于信号处理的所有字段

        /*
            5) pending: 存放私有挂起信号的数据结构
        */
        struct sigpending pending;
    

    struct sigpending pending;就是用来做信号标记的,给一个进程发送的所有信号都存储在这个结构体中,那么它是如何标记的呢,我们可以对这个结构体进行展开。

    struct sigpending {
            struct list_head list;
            sigset_t signal;
    };
    
    /* A `sigset_t' has a bit for each signal.  */
    # define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
    typedef struct
      {
        unsigned long int __val[_SIGSET_NWORDS];
      } __sigset_t;
    

    pending结构体包含2个字段struct list_headsigset_t,其中sigset_t这个结构体只有一个数组成员,在32位环境下,这个数组大小为32;在64位环境下,这个数组大小为16。个人理解这个数组大小标记了进程可以同时接收的最大信号数目。不管是32位环境还是64位环境,均只能最大容纳16个信号(32位环境下,需要两个数组元素表示64个不同的信号)。

    现在我们就可以理解,当某一个进程发送一个信号给当前进程时,操作系统就会将该进程对应的pending集合中表示相应信号的位图的二进制位中0改为1。位图只是用来标记有没有待处理的信号。

    信号的分类

    Linux操作系统有64中不同的信号,分为非可靠信号(1-32)和可靠信号(33-64)。二者的区别主要体现在注册方面。

    非可靠信号

    试图对一个进程发送一个非可靠信号时,若发现位图上对应的位为0,则置为1;若发现位图上对应的位已经为1,则直接返回。简单地说就是若信号还未注册,则注册一下,若已经注册,则什么都不做

    可靠信号注册

    当试图对一个进程发送一个可靠信号时,若发现位图上对应的位为0,则置为1,若发现位图上对应的位已经为1,对该位不进行操作但依旧在链表里加入一个待处理节点。也就是说,每次对进程发送一个可靠信号时,不管该进程之前是否收到过相同的信号,总是会在list_head链表里加入待处理节点

    未完待续。。。。

  • 相关阅读:
    CF1539 VP 记录
    CF1529 VP 记录
    CF875C National Property 题解
    CF1545 比赛记录
    CF 1550 比赛记录
    CF1539E Game with Cards 题解
    CF1202F You Are Given Some Letters... 题解
    vmware Linux虚拟机挂载共享文件夹
    利用SOLR搭建企业搜索平台 之九(solr的查询语法)
    利用SOLR搭建企业搜索平台 之四(MultiCore)
  • 原文地址:https://www.cnblogs.com/wangdongfang/p/13800457.html
Copyright © 2011-2022 走看看