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

    未完待续。。。。

  • 相关阅读:
    C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本
    C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本
    C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本
    C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本
    《程序员,你伤不起》 回答热心爸爸读者的疑问
    入驻微信公众号平台【今日热点在线】、【大数据躺过的坑】和【九哥九嫂小日子】,欢迎关注
    入驻百家号【九哥聊IT】和【九哥九嫂小日子】,欢迎关注
    全网最详细的最新稳定OSSEC搭建部署(ossec-server(CentOS7.X)和ossec-agent(CentOS7.X))(图文详解)
    CentOS 7的安装详解
    全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装爬虫框架Scrapy(离线方式和在线方式)(图文详解)
  • 原文地址:https://www.cnblogs.com/wangdongfang/p/13800457.html
Copyright © 2011-2022 走看看