unix环境高级编程-信号(2)
函数kill和raise:
kill函数将信号发送给进程或进程组,raise函数则运行进程向自身发送信号。
kill的pid参数有以下四种不同情况:
pid>0,将该信号发送给进程ID为pid的进程
pid==0,将该信号发送给与发送进程属于同一进程组的所有进程。
pid<0 ,将该信号发送给进程组ID等于pid绝对值
pid==-1,将该信号发送给发送进程有权限发送信号的所有进程。
函数alarm和pause:
使用alarm函数可以设置一个定时器,在某个时刻定时器超市,产生SIGALRM信号,若忽略或不捕捉此信号,则默认动作是终止调用该alarm函数的进程。
虽然SIGALRM的默认动作是终止进程,但大多数使用闹钟的进程捕捉此信号。
pause函数:使调用进程挂起直到捕捉到一个信号。
#include<unistd.h>
int pause(void);
只有执行了一个信号处理程序并从其返回时,pause才返回。
利用alarm和pause函数可使自己休眠一段时间。
#include <signal.h>
#include <unistd.h>
static void sig_alrm(int signo)
{
//nothing to do ,just return to wake up the pause
}
unsigned int sleep1(unsigned int seconds)
{
if(signal(SIGALAM,sig_alrm)==SIG_ERR)
return (seconds);
alarm(seconds); //开始计时器
pause(); //下一个信号会唤醒
return (alarm(0));//关闭计时器,返回剩余时间
}
这个是sleep简单而不完整的实现,有几个问题,在第一次调用alarm和pause有一个竞争条件,可能alarm在调用pause之前就超时,并调用了信号处理程序sig_alrm,这种情况下,调用pause后,如果没有捕捉到其他信号,调用者将永远被挂起。
除了用来实现sleep函数外,alarm还常用于对可能阻塞的操作设置时间上限值,例如,程序中有一个读低速设备的可能阻塞的操作,我们希望超过一定时间就停止执行该操作。
信号集:需要一个能够表示多个信号的数据类,将在sigprocmask类函数中使用这种数据类型,以便告诉内核不允许发生该信号集中的信号,
函数sigemptyset初始化由set指向的信号集,清除其中所有信号,函数sigfillset初始化由set指向的信号集,使其包括所有信号,所有应用程序在使用信号集前,要对该信号集调用sigemptyset或sigfillset一次,因为c编译程序将不赋予初值的外部变量和静态变量都初始化为0,。
一旦初始化了一个信号集,以后就可在信号集中增、删特定的信号。sigiaddset将一个信号添加到已有的信号集,sigdelset删除一个信号。
如果实现的信号数目少于一个整型量所包含的位数,可用一位代表一个信号的方法实现信号集。sigemptyset函数将整型设置为0,sigfillset函数将整型设置为1,sigaddset开启一位就是将该位设置为1,sigdelset关闭一位将该位设置为0。sigismember测试一个指定的位,因为没i有信号编号为0,从信号编号减一得到要处理位的位编号。
函数sigaction:检查或修改与指定信号相关联的处理动作,此函数取代unix早起的signal函数。
参数signo是信号编号,若act指针非空,则要修改其动作,若oact指针非空,则系统经过oact指针返回该信号的上一个动作。此函数使用以下结构
函数sigsetjmp和siglongjmp
之前用于非局部转移的setjmp和longjmp函数,在信号处理函数中经常调用longjmp函数以返回到程序的主循环中,但是调用longjmp有个问题,当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被自动加到进程的信号屏蔽字中,这阻止了后来产生的这种信号中断该信号处理程序。
函数abort:使程序异常终止
此函数将SIGABRT信号发送给调用进程,在进程终止之前由其窒息感所需的清理操作,如果进程并不在信号处理程序中终止自己,那么当信号处理程序返回时,abort终止该进程。
函数sleep:
此函数使调用进程被挂起,直到满足下面两个条件之一:
1.以及过了seconds所指定的墙上时钟时间
2.调用进程捕捉到一个信号并从信号处理程序返回。
尽管sleep函数可以用alarm函数实现,但这并不是必须的。使用alarm函数可鞥两个函数之间还会互相影响。
nanosleep函数:与sleep函数类似,但提供了纳秒级的精度。
作业控制信号:
在那么多信号中,与作业控制有关的是6个:
SIGCHLD 子进程已停止或终止
SIGCONT 如果进程已停止,则使其继续运行
SIGSTOP 停止信号
SIGTSTP 交互式停止信号
SIGTTIN 后台进程组成员读控制终端
SIGTTOU 后台进程组成员写控制终端
除了SIGCHLD之外,大多数应用程序并不处理这些信号,交互式shell则通常会处理这些信号的所有工作,当键入挂起字符(crtl+Z),SIGTSTP被送至前台进程组的所有进程,当我们通知在前台或后台恢复运行一个作业时,shell向该作业的所有进程发送SIGCONT信号。
在作业控制信号之间还存在某种交互,比如当一个进程产生4种停止信号(SIGTSTP、SIGSTOP、SIGTTIN或SIGTTOU)中的任意一种时,对该进程的任一未决信号SIGCONT信号就被丢弃,与此类似,当对一个进程产生SIGCONT信号时,对同一进程的任一未决停止信号被丢弃。
信号名和编号:
信号名和编号之间如何进行映射,系统提供数组:
extern char *sys_siglist[];
数组下标是信号编号,数组中的元素是指向信号名符串的指针
posted on 2016-08-01 21:07 sichenzhao 阅读(125) 评论(0) 编辑 收藏 举报