信号

信号

信号是软件中断,可通过敲系统命令“kill -l”查看可用的信号值,如“kill -9 pid”就是常用的发送杀死进程信号,kill默认发送SIGTERM终止信号。

信号值

相应的kill函数将信号发送给进程或进程组,raise函数则运行进程向自身发送信号。

#include <signal.h>
int kill(pid_t pid, int signo);
int raise(int signo);

信号的处理有三种方式:
(1)忽略此信号,大多数信号都可使用这两种方式进行处理,但有两种信号却不能忽略,他们是SIGKILL和SIGSTOP
(2)捕捉信号,如捕捉到SIGCHLD信号,则表示一个子进程已经终止或停止,所以此信号的捕捉函数可以调用waitpid以取得该子进程的进程ID以及它的终止状态,以便系统释放相应的资源。如SIGCHLD被忽略,总是会产生僵死子进程,无法正常结束。
(3)执行系统默认动作,大多数系统默认动作是终止进程

如要捕捉信号并处理,简单的接口函数是signal函数

#include <signal.h>
void (*signal(int signo, void (*func)(int)))(int);
返回值:若成功则返回信号以前的处理配置,若出错则返回SIG_ERR;

signo是上图中对应的信号名,func的值是常量SIG_IGN(忽略),SIG_DFL(默认)或当接到此信号后要调用的函数地址。


当执行一个程序时,所有信号的状态都是系统默认或者忽略。通常所有信号都被设置为它们的默认动作,除非调用exec的进程忽略该信号。确切地讲,exec函数将原先设置为要捕捉的信号都更改为他们的默认动作,其他信号的状态则不变。
而当一个进程调用fork时,其子进程继承父进程的信号处理方式。因为子进程在开始时复制了父进程的存储映像,所以信号捕捉函数的地址在子进程中是有意义的。

如果进程在执行一个低速系统调用而阻塞期间捕捉到一个信号,则系统调用就被中断不再继续执行。该系统调用返回出错,其errno被设置为EINTR。这样处理的理由是:因为一个信号发生了,进程捕捉到了它,这意味着已经发生了某件事情,所以是个应当唤醒阻塞的系统调用的好机会。

为了支持这种特性,将系统调用分成两类:低速系统调用和其他系统调用。低速系统调用是可能会使进程永远阻塞的一类系统调用。

与被中断的系统调用相关的问题是必须显式地处理出错返回。典型的代码如下:

again:
  if ((n = read(fd, buf, BUFFSIZE)) < 0)
  {
    if (errno == EINTR)
      go again;
    // handle other errors
  }

为帮助应用程序使其不必处理被中断的系统调用,4.2BSD引入了某些被中断系统调用的自动重启动。自动重启动的系统调用包括ioctl、read、readv、write、writev、wait和waitpid。前5个函数只有对低速设备进行操作时才会被信号中断。而wait和waitpid在捕捉到信号时总是被中断。因为这种处理方式也会带来问题,所以某些应用程序并不希望这些函数被中断重启动,在4.3BSD运行进程基于某个信号禁用此功能。
POSIX.1允许实现重启动系统调用,但这并不是必须的。Single UNIX Specification将SA_RESTART定义为对sigaction的XSL扩展,以允许应用程序要求重启动被中断的系统调用。

不过对于套接字编程中的connect函数是不能重启的,若connect函数返回一个EINTR错误,不能再次调用它,否则将立即返回一个错误(EADDRINUSE)。针对connect不能重启的处理方法是,必须调用select来等待连接完成。

另外早期版本signal在接到信号并进行处理时,随即将信号动作复位为默认值,如想后续继续捕捉该信号处理,需在处理函数前面再次signal注册,但从处理函数开始执行到重新注册该信号之间有个空隙,这个时候信号default处理掉了。
新接口sigaction捕捉到信号后,默认不会将信号动作复位为默认值。现很多平台signal函数用sigaction实现,从可移植性考虑,建议直接调用sigaction函数。

《UNIX环境高级编程》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值