• 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链表里加入待处理节点

    未完待续。。。。

  • 相关阅读:
    May 9, 17:3020:00, 1479, "Concentrationcompactness/Rigidity method" lecture 4 by Yang Lan
    May 21, 10:0011:00, 1303, "Capacity, Primeter and ADMmass " by Jie Xiao
    课程期末安排
    问题: Schrodinger方程的广义Strichartz估计
    May 21, 11:1012:10 "On small solutions for nonlinear wave equations in exterior domains " by Makoto NAKAMURA
    SQL Server2019数据库备份与还原脚本,数据库可批量备份
    记一次 IIS 站点配置文件备份和还原,物理路径文件批量备份
    从网上收集的一些图片方面的操作
    android获取本地IP
    java利用httpconnect向服务器发送信息与接收回馈信息
  • 原文地址:https://www.cnblogs.com/wangdongfang/p/13800457.html
Copyright © 2020-2023  润新知