Linux 进程学习(五)

    xiaoxiao2025-09-10  527

    屏蔽信号:  在 sigaction 的使用中,我们已经看到了表示信号集的 sigset_t 型数据。在 Linux 上有一组函

    数专门用于对信号集进行操作:  #include <signal.h>  int sigemptyset(sigset_t *set);  int sigfillset(sigset_t *set);  int sigaddset(sigset_t *set, int signum);  int sigdelset(sigset_t *set, int signum);   int sigismember(const sigset_t *set, int signum);

     set 参数指向要操作的信号集,而 signum 参数则代表一个指定的信号,各个函数的作用如下:  ◆ sigemptyset:清空信号集,返回 0 表示成功,-1 表示失败;  ◆ sigfillset:将所有信号加入信号集,返回 0 表示成功,-1 表示失败;  ◆ sigaddset:将指定信号加入信号集,返回 0 表示成功,-1 表示失败;  ◆ sigdelset:将指定信号从信号集中去除,返回 0 表示成功,-1 表示失败;  ◆ sigismember:判断一个指定的信号是否在信号集中,返回 1 表示在信号集中,0 表示不在信

    号集中,-1 表示有错误发生。

     信号集在使用前需要先用 sigemptyset 或 sigfillset 函数进行初始化,然后用 sigaddset 或

    sigdelset 函数增加或去除需要的信号。  在代码中也可以直接设置或获取进程的信号掩码:  int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);  ◆ how:指定操作信号掩码的方式。  ◆ set:指向用于设置信号掩码的信号集。  ◆ oldset:用于返回原来的信号掩码。  ◆ 返回值:0 表示成功,-1 表示失败。

     sigprocmask 函数将根据参数 how 指定的方式,设置当前进程的信号掩码,并把原来的信号掩码

    保存在参数 oldset 指向的信号集中返回。如果 set 参数为 NULL,则不修改信号掩码;如果 oldset 参数

    为 NULL,则不返回原来的信号掩码。how 有以下三个取值:  ◆ SIG_BLOCK:将 set 参数指向信号集中的信号加入到信号掩码中。  ◆ SIG_UNBLOCK:将 set 参数指向的信号集中的信号从信号掩码中删除。  ◆ SIG_SETMASK:将 set 参数指向信号集设置为信号掩码。

     因此,屏蔽某个信号可以有两种方式,下面以 SIGUSR1 信号为例进行说明:  第一种方式为使用 SIG_BLOCK 操作方式,代码如下:  sigset_t sigset;  sigemptyset(&sigset);  sigaddset(&sigset, SIGUSR1);  sigprocmask(SIG_BLOCK, &sigset, NULL);     第二种方式为使用 SIG_SETMASK 操作方式,代码如下:  sigset_t set;  sigprocmask(SIG_SETMASK, NULL, &set);   //先得到当前的信号掩码  sigaddset(&set, SIGUSR1);               //将要屏蔽的信号加入  sigprocmask(SIG_SETMASK, &set, NULL);  

     同时,要解除对信号的屏蔽,也有两种方式,仍以 SIGUSR1 信号为例:  第一种方式,使用 SIG_UNBLOCK 操作方式:  sigset_t sigset;  sigemptyset(&sigset);  sigaddset(&sigset, SIGUSR1);  sigprocmask(SIG_UNBLOCK, &sigset, NULL);

     第二种方式,使用 SIG_SETMASK 操作方式:  sigset_t set;  sigprocmask(SIG_SETMASK, NULL, &set);  //先得到当前的信号掩码  sigdelset(&set, SIGUSR1);              //将要解除屏蔽的信号去除  sigprocmask(SIG_SETMASK, &set, NULL);

     

    信号安全函数:  如前所述,进程在收到信号并对其进行处理时,会中断当前正在执行的指令序列,而去执行信号处

    理函数。但是信号的传递是异步的,系统无法确定何时传递信号给进程。如果进程在收到信号时正在执行某

    个不可重入的函数,这时捕捉到信号,进程就会转而去执行信号处理函数。如果在这个信号处理函数中又再

    次调用了同一个函数,就有可能产生问题。  因此有些函数时不能在信号处理函数中调用的,那些可以在信号处理函数中调用且不会有潜在问题

    的函数称为对信号安全的。下表列出了 Linux 系统中的信号安全函数,对于不在这个表中的函数,如果要

    在信号处理函数中调用,则需谨慎处理。

     

    转载请注明原文地址: https://ju.6miu.com/read-1302489.html
    最新回复(0)