美文网首页
信号(三)·

信号(三)·

作者: 千里山南 | 来源:发表于2016-02-17 21:17 被阅读55次

2016-02-17

alarm 和 pause函数

使用alarm函数可以设置一个时间值,在将来的某个时刻该时间值会被超过。产生SIGALRM信号。如果不忽略或不捕捉此信号,则其默认动作是终止该进程。

#include<unistd.h>
unsigned int alarm(unsigned int seconds) //seconds单位为秒

每个进程只能有一个脑中时间。如果在调用alarm时,以前已经为该进程设置过闹钟时间,而且此闹钟没有超时,则该闹钟时间的剩余值作为本次alarm的返回值。以前登记的闹钟时间被新值所取代。
pause函数使调用进程挂起直到捕捉到一个信号。

#include <unistd.h>
int pause(void);

只有执行了一个信号处理程序并从其返回pause才返回。这种情况下pause返回-1 errno设置为EINTR

信号集

我们需要有一个能表示多个信号(信号集)的数据类型。将在sigprocmask这样的函数中使用这种数据类型。以告诉内核不允许发生该信号集中的信号。如前所述信号种类数目有可能超过一个整形来那个所包含的位数,所以一般而言不能用整型量中的一位代表一种信号。POSIX定义数据类型sigset_t以包含一个信号集,并且定义了5个处理信号集的函数。

#include<signal.h>
int sigemptyset (sigset_t *set)
int sigfillset(sigset_t *set)
int sigaddset(sigset_t *set, int signo)
int sigdelset(sigset_t *set, int signo) //四个函数若成功返回0,出错返回-1
int sigismenber(const sigset_t *set, int signo)

函数sigemptyset初始化由set指向的信号集,使排除其中的说由信号。函数sigfillset初始化由set指向的信号集,使其包括所有的信号。所有应用程序在使用信号集前,要对该信号集调用sigemptyset或者sigfillset初始化。这是因为c编译程序将不赋初值的外部和静态变量都初始化为0,而这是否与给定系统上信号集的实现相对应并不清楚。
一旦已经初始化了一个信号集,以后就可在该信号集中增删特定的信号。函数sigaddset将一个信号添加到现存信号集中,sigdelset则从信号集中删除一个信号。

sigprocmask函数

一个进程的信号屏蔽字规定了当前阻塞而不能传递给该进程的信号集。调用函数sigprocmask可以检测或者更改进程的信号屏蔽字。
int sigptocmask(int how, const sigset_t *set, sigset_t *oset)
首先oset是非空指针,该进程的当前信号屏蔽字通过oset返回。其次若set是一个非空指针,则参数how指示如何修改当前信号屏蔽字。how的取值如下:

  • SIG_BLOCK 该进程新的信号屏蔽字是当前信号屏蔽字和set的并集
  • SIG_UNBLOCK set包含了我们希望解除阻塞的信号
  • SIG_SETMASK 该进程新的信号屏蔽字是set指向的值

如果set是个空指针,则不改变该进程的信号屏蔽字,how的值也就无意义了
如果在调用sigprocmask后有任何未决的不再阻塞的信号,则在sigprocmask返回前,至少将此信号递送给该进程一次(如果系统不支持信号排队)。

sigpending函数

sigpending返回对于调用进程被阻塞不能递送和当前未决的信号集。该信号集通过set参数返回
int sigpending(sigset_t *set)

sigaction函数

sigaction函数是检查或者修改与指定信号相关联的处理动作。
int sigaction(int signo, const struct sigaction *act, struct sigaction *oact)
其中,参数signo是要检查或者修改信号的编号。若act指针非空,则要修改其动作。如果oact指针非空,则系统返回该信号的原先动作。

struct sigaction {
    void (*sa_handler)();
    sigset_t sa_mask;
    int sa_flags;
}

当更改信号动作时,如果sa_handler指向一个信号捕捉函数则sa_mask字段说明了一个信号集,在调用信号捕捉函数之前,该信号集要加到进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字恢复为原先值。这样,在调用信号处理程序时就能阻塞某些信号。在信号处理程序被调用时,系统建立的新的信号屏蔽字会自动包括正在被递送的信号。因此保证了在处理一个给定的信号时,如果这种信号再次发生,那么它会被阻塞到对前一个信号处理结束为止。若同一个信号发生多次,通常它们并不排队,所以如果在某种信号被阻塞时它发生了五次,那么对这种信号解除阻塞后其信号处理函数通常只会被调用一次。

sigsetjmp和siglongjmp

在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回。调用longjmp时有一个问题,当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被自动地加到进程的信号屏蔽字中。这阻止了后来产生的这种信号中断此信号处理程序。为了允许两种形式并存,POSIX并没有说明setjmp和longjmp对信号屏蔽字的作用,而是定义了两个新函数sigsetjmp和siglongjmp。在信号处理程序中作非局部转移时应当使用这两个函数。
int sigsetjmp(sigjmp_buf env, int savemask)
void siglongjmp(sigjmp_buf env, int val)
这两个函数和setjmp,longjmp之间的唯一区别是sigsetjmp增加了一个参数。如果savemask非0,则sigsetjmp在env中保存进程的当前信号屏蔽字。调用siglongjmp时,如果带非0savemask的sigsetjmp调用已保存了env则siglongjmp从其中恢复保存的信号屏蔽字。

sigsuspend函数

更改进程的信号屏蔽字可以阻塞或者解除阻塞所选择的信号。使用这种技术可以保护不希望由信号中断的代码临界区。如果希望对一个信号解除阻塞,然后pause以等待以前被阻塞的信号。如果在解除对信号的阻塞和pause之间发生了此信号,则信号将被丢失。为了纠正此问题,需要在一个原子操作中实现恢复信号屏蔽信号字,然后使进程睡眠,这种功能是由sigsuspend函数所提供的。

相关文章

  • 信号(三)·

    2016-02-17 alarm 和 pause函数 使用alarm函数可以设置一个时间值,在将来的某个时刻该时间...

  • 信号(三):Bash 中的信号

    当没有任何捕获时,一个交互式 Bash Shell 会忽略 SIGTERM 和 SIGQUIT 信号。由 Bash...

  • 信号处理(三)

    本篇介绍 本篇接续信号处理的介绍。 图像中的信号处理 信号处理在采样图像中使用的最为广泛。比如图像的模糊就是将图像...

  • 信号#1

    信号的概念 取决于进程的要求,内核对Signal信号有如下三种行为: 忽略信号 抓住这个信号并且对这个信号进行处理...

  • 华与华方法(10)传播第三原理

    传播第三原理——信号能量原理。 第三原理与第一原理相关,第三原理就是,刺激信号越强,信号反射越大。 巴浦洛夫刺激反...

  • 信号控制 & expect

    一,信号说明 二,信号处理 捕捉信号并处理 三,hup信号 ---->如何让一个进程脱离当前窗口运行 四, exp...

  • 汽轮机ETS保护条件

    1) 凝汽器真空低:三个真空低跳机信号三取二后和三个真空低闭锁信号相与输出真空低跳机保护信号; 2) 润滑油压低:...

  • dispatch_semaphore_t

    dispatch_semaphore_t :信号量包含三个函数:1、创建信号量 2、增加信号量 3、削减信号量 注...

  • 20170919原油交易总结(-50)

    信号一 信号分析 第一单(做空,亏损15个点) 信号二 信号分析 第二单(做空,亏损17个点) 第三单(做空,亏损...

  • 2020-02-22

    04 韩国疫情告急,三个信号值得警惕 据长安街知事总结,韩国疫情告急,三个信号值得警惕: 第一个信号:青瓦台“中招...

网友评论

      本文标题:信号(三)·

      本文链接:https://www.haomeiwen.com/subject/aojmkttx.html