Linux系统编程入门--信号详解--适合零基础小白!!!

  • 目录

    信号的基本结论

    信号的概念

    信号处理

    信号产生

    信号的发送

    系统调用

    模拟实现kill命令

    软件条件

    设置闹钟

    异常

    Core && Term

    _信号保存

    信号集:sigset_t

    操作函数

    三张信号表

    _信号处理

    系统调用

    _重入函数

    volatile关键字

    重谈进程等待

    信号处理过程中的三张位图表:block,pending,handler


  • 信号的基本结论

    • 信号在OS中随时都可能产生!
    • 进程要认识这个信号
    • 进程知道信号产生了,该如何处理?
    • 进程可能正在做着更重要的事情,把到来的信号暂不处理。
      • 进程记得这个信号
      • 进程在合适的时候会去处理这个信号
  • 信号的概念

    • Linux系统提供的一种,向指定进程发送特定事件的方式
    • 信号产生是异步的
  • 信号处理

    • a.默认动作:终止自己,暂停,忽略...
    • b.忽略动作
    • c.自定义处理---信号的捕捉
      • 对信号的自定义捕捉,我们只需要捕捉一次,后续一直有效
      • signal:当进程收到sig信号时,会使用handler方法
      • 忽略一个信号 :在signal的第二个参数传递一个宏:SIG_IGN,使用默认的:SIG_DFL
  • 信号产生

    • 信号的发送

      • 修改指定进程pcb中的信号的指定位图,0->1,写信号
      • 键盘可以产生信号
    • 本质是OS更改pcb中的状态(位图)
    • 系统调用

      • kill:

        • 系统调用的kill
          • kill -l :查询信号种类
      • 模拟实现kill命令

      • raise函数:

      • 作用:给当前进程发送sig号信号

      • abort函数:

      • 作用:终止进程,向调用进程发送6号信号
        • 不接受信号的自定义捕获的宏

    • 软件条件

      • 设置闹钟

        • alarm:
        • seconds秒后OS发送14号信号
        • OS要对闹钟进行管理:先描述在组织
          • struct alarm{}
          • 被大小堆管理
      • IO很慢
      • alarm(0)表示:取消闹钟,alarm的返回值是上一个闹钟的剩余时间
      • 闹钟默认只触发一次!
    • 异常

      • 1.SIGFPE---8号信号
      • 2.SIGSEGV---11号信号---段错误---越界
        • 页表转换失败!
      • 再谈cpu
        • cpu是如何得知运算是正常的还是异常的?
    • Core && Term

      • Core:让进程异常终止,但是会形成一个debug信息
        • debug信息:形成一个core文件--->存储的是进程退出的时候的镜像数据----核心转储
      • Term:让进程异常终止
  • _信号保存

    • 进程可以选择阻塞某个信号
      • 阻塞一个信号,那么对应的信号一旦产生,永不递达,直到主动解除阻塞!
    • 信号集:sigset_t

      • 操作函数
        • 1.sigprocmask函数:
        • 作用:修改进程内核的block表!

          • 第一个参数
            • SIG_BLOCK
            • SIG_UNBLOCK
            • SIG_SETMASK
          • 第三个参数:给用户返回一张原有的位图表
          • 解除屏蔽后,一般会立即处理当前被接触的信号(如果被pending)!!
          • pending位图是在执行handler方法之前就被清零了!!
        • sigpending函数:
        • 作用:获取当前进程的pending位图
        • 清空输入的set位图
        • 增加指定信号到set信号集中
        • 判断一个信号在不在一个信号集中
      • 三张信号表

        • 阻塞表:block
        • 递达表:pending
        • 信号处理表:handler
  • _信号处理

    • 信号的捕捉:要经历4次状态的切换!在内核态切换回用户态的时候,会检测信号的状态
    • _地址空间
      • 不同进程之间共享一份内核级页表--->【3,4】GB
    • _键盘输入数据的过程
      • 按下键盘产生中断信号,通过某种硬件被cpu读取到,转而由cpu向OS中的中断向量表中(函数指针数组)中下标访问键盘方法!!
    • 内核态-->用户态之间的切换
      • 2者相互隔开的!用户态[0,3]GB,内核【3,4】GB,二者互不干扰(是由CPU保证的!)
      • 程序运行从用户态切换到内核态的操作:中断/异常/系统调用
    • 系统调用

      • 对特定信号进行捕捉

        • 可以查阅man手册-->sigaction-->struct sigation结构体
    • 正在处理被捕捉的特定的信号时,该信号种类将会被OS屏蔽,直到本次特定的信号处理结束!
    • 如果想要同时屏蔽多个信号,可以通过sigaddset设置进mask中
  • _重入函数

    • _可重入函数
    • _不可重入函数
      • 大部分函数都不是可重入函数!
  • volatile关键字

    • 编译器的优化级别: O0 O1 O2 O3
      • 当开启优化等级时,CPU寄存器会隐藏内存中的真实值 (就不会每次都去内存中拿值)
    • volatile关键字:修饰变量,让代码无视优化,保证内存的可见性 ---->volatile int a = 0;
  • 重谈进程等待

    • 子进程退出的同时会发送SIGCHLD---17号信号
    • 既然子进程退出会发送信号,那么以后就不用在main函数的父进程代码中去等待子进程了,可以通过signal捕捉信号,通过handler方法去等待子进程,waitpid(-1,nullptr,0);如果多个子进程同时退出,那么就需要通过循环去不断的等待对应的子进程。
    • 通过 signal(SIGCHLD,SIG_IGN):自动回收子进程!
  • 信号处理过程中的三张位图表:block,pending,handler

    • _block
      • 判断某个信号是否为阻塞状态,是为1,否为0,注意!如果信号被阻塞,仍然可以被添加进pending表中!!
    • _pending
      • pending集合代表的是该信号是否产生了,如果对应的比特位为1,代表着该信号已经产生,如果此时该信号未被阻塞,那么就会在合适的时候对该信号进行处理。(这个合适的时候就是当进程从内核态转化为用户态的时候)。 处理的方式就是对应handler表中的方式
    • _handler
      • handler集合代表着该信号的处理方式,处理方式有三种,如下:
      • 忽略一个信号 :在signal的第二个参数传递一个宏:SIG_IGN,使用默认的:SIG_DFL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值