26 August 2014

信号的处理


  1. 忽略此信号。有两种信号不能忽略,它们是SIGKILL和SIGSTOP,原因是:它们向内核和超级用户提供了使进程终止或停止的可靠方法。
  2. 捕捉信号。不能捕捉SIGKILL和SIGSTOP信号。
  3. 执行系统默认动作。

exec函数会将原先设置为要捕捉的信号都更改为默认动作,其他信号的状态则不变,因为信号捕捉函数的地址很可能在所执行的新程序文件中已毫无意义。

函数


  • signal()函数的限制:不改变信号的处理方式就不能确定信号的处理方式。
  • sigaction()函数可以检查或修改一个信号的处理方式,而无需改变它。
  • kill()函数将信号发送给进程或进程组。
  • raise()函数则允许进程向自身发送信号。
  • laarm()函数可以设置一个定时器,在将来的某个时刻该定时器会超时,并产生SIGALRM信号。
  • pause()函数使调用进程挂起直至捕捉到一个信号。

可重入函数:能够被同时调用,且能工作正常。

异步信号安全:除了可重入以外,在信号操作期间,它会阻塞任何会引起不一致的信号发送。

可靠信号术语和语义


当一个信号产生时,内核通常在进程表中以某种形式设置一个标志。

在信号产生(generation)和递送(delivery)之间的时间间隔内,称信号是未决的(pending)。

进程可以选用“阻塞信号递送”。如果为进程产生了一个阻塞的信号,而且对该信号的动作是系统默认动作或捕捉信号,则为该进程将此信号保持为未决状态,直到进程对此信号解除阻塞,或者将对此信号的动作更改为忽略。

进程调用sigpending函数来判定哪些信号是设置为阻塞并处于未决状态的。

如果在进程解除对某个信号的阻塞之前,这种信号发生了多次,那么将如何呢?POSIX.1允许系统递送信号一次或多次。如果递送该信号多次,则称这些信号进行了排队。但是除非支持POSIX.1实时扩展,否则大多数UNIX并不对信号排队,而只是递送这种信号一次。

如果由多个信号要递送给一个进程,那将如何呢?POSIX.1并没有规定这些信号的递送顺序。但是POSIX.1基础部分建议:在其他信号之前递送与进程当前状态有关的信号。

每个进程都有一个 信号屏蔽字 ,它规定了当前要阻塞递送到该进程的信号集。

进程调用sigprocmask函数来检测和更改其当前信号屏蔽字。

在信号处理程序中进行非局部转移时应当使用这两个函数:sigsetjmp()siglongjmp

信号排队:sigqueue

5个处理信号集的函数


  1. sigemptyset()初始化由set指向的信号集,清除其中所有信号;
  2. sigfillset()初始化由set指向的信号集,使其包括所有信号;
  3. sigaddset()将一个信号添加到已有的信号集中;
  4. sigdelset()从信号集中删除一个信号。

函数sigsuspend


进程的信号屏蔽字设置为由sigmask指向的值。在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程挂起。如果捕捉到一个信号而且从该信号处理程序返回,则sigsuspend返回,并且该进程信号屏蔽字设置为调用sigsuspend之前的值。

函数abort


此函数将SIGABRT信号发送给调用进程。ISO C要求若捕捉到此信号而且相应信号处理程序返回,abort仍不会返回到其调用者。在进程捕捉SIGABRT的意图:在进程终止之前由其执行所需的清理操作。

函数sleep、nanosleep和clock_nanosleep


函数使调用进程挂起知道满足以下条件之一:

  • 已经过了指定时间;
  • 调用进程捕捉到一个信号并从信号处理程序返回。

作业控制信号


  • SIGCHLD 子进程已停止或终止
  • SIGCONT 如果进程已停止,则使其继续运行
  • SIGSTOP 停止信号,不能被捕捉或忽略
  • SIGTSTP 交互式停止信号
  • SIGTTIN 后台进程组成员读控制终端
  • SIGTTOU 后台进程组成员写控制终端

信号名和信号编号


给出一个信号编号,strsignal将返回描述该信号的字符串。