当前位置:   article > 正文

【Linux】进程信号_3

【Linux】进程信号_3


八、进程信号

2. 信号的保存

实际执行信号的处理动作称为信号递达(Delivery)
信号从产生到递达之间的状态,称为信号未决(Pending)。
进程可以选择阻塞 (Block )某个信号。
被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。
注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

在进程的PCB中,有两个位图,一个是判断是否收到相应信号的位图pending,一个是决定该位置的信号是否阻塞的位图block。
在这里插入图片描述
handler表是一组函数指针,决定信号的执行方法。
调用函数 sigprocmask 可以读取或更改进程的信号屏蔽字(阻塞信号集)。
在这里插入图片描述

int main()
{
    // 创建阻塞信号集
    sigset_t block, oblock;
    
    // 清空信号集
    sigemptyset(&block);
    sigemptyset(&oblock);

    // 将2号信号添加进阻塞信号集
    sigaddset(&block, 2);
	
	// 将阻塞信号集设置到内核中
    int n = sigprocmask(SIG_SETMASK, &block, &oblock);
    assert(n == 0);

    while (true)
    {
        // 创建pending信号集
        sigset_t pending;
        sigemptyset(&pending);

        // 获取pending信号集
        n = sigpending(&pending);
        assert(n == 0);

        // 打印pending信号集
        PrintSig(pending);
        sleep(1);
    }

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在这里插入图片描述
9号信号、19号信号无法被屏蔽,18号信号会做特殊处理。操作系统不允许出现 金刚不坏 的进程。
如何解除屏蔽?

	while (true)
    {
        int cnt = 0;
        // 创建pending信号集
        sigset_t pending;
        sigemptyset(&pending);

        // 获取pending信号集
        n = sigpending(&pending);
        assert(n == 0);

        // 打印pending信号集
        PrintSig(pending);
        ++cnt;
        if (cnt == 20)
        {
            // 解除阻塞信号集
            n = sigprocmask(SIG_UNBLOCK, &block, &oblock);
            assert(n == 0);
        }
        sleep(1);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3. 信号的处理


未完待续

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/776519
推荐阅读
相关标签
  

闽ICP备14008679号