kill 函数和 raise 函数
kill 函数是将信号发送给进程或进程组,raise 函数是将信号发送给自身,他们定义及说明如下所示:
/* 信号发送与捕获 */
/*
* 函数功能:将信号发送给进程或进程组;
* 返回值:若成功则返回0,若出错则返回-1;
* 函数原型:
*/
#include <signal.h>
int kill(pid_t pid, int signo);
/*说明:
* signo 是信号类型;
* pid有以下四种情况:
* (1)、pid >0,将该信号signo发送给进程ID为pid的进程;
* (2)、pid ==0,将该信号signo发送给与发送进程属于同一进程组的所有进程,
* 而且发送进程具有向这些进程发信号的权限;
* (3)、pid <0,将该信号signo发送给其进程组ID等于pid绝对值,而且发送进程具有
* 其所发送信号的权限;
* (4)、pid ==-1,将该信号signo发送给发送进程有权限向他们发送信号的系统上的所有进程;
*/
/*
* 函数功能:向进程自身发送信号;
* 返回值:若成功则返回0,若出错则返回-1;
* 函数原型:
*/
int raise(int signo);
/*
* raise(signo)等价于kill(getpid(),signo);
*/
超级用户可以将信号发送给任一进程,对于非超级用户,其基本规则是发送者的实际或者有效用户ID必须等于接受者的实际或者有效用户ID。但也有一个特例:如果被发送的信号是 SIGCONT,则进程可以将它发送给属于同一会话的任何进程。
如果 signo 参数为 0(POSIX.1将其定义为空信号),kill 仍执行正常的错误检查,但不发送信号。这常被用来检测某一进程是否存在。如果向一个不存在的进程发送信号,则 kill 返回 -1,并将 errno 设置为 ESRCH。但是,UNIX系统在经过一段时间后会重新使用进程ID,所以一个现有的具有所给定进程ID的进程可能并不是你真正想检测的进程。
alarm 函数和pause 函数
使用 alarm 函数可以设置一个计时器,在将来某个指定的时间该计时器会超时。当计时器超时时,产生SIGALRM信号,如果不忽略或捕捉此信号,则其默认动作是终止调用该 alarm 函数的进程。每个进程只能有一个闹钟。如果在调用alarm 时,已经为该进程设置过闹钟,而且它还没有超时,则将该闹钟的剩余时间值作为本次alarm 调用的返回值。以前的闹钟则被新值代替。
pause 函数使调用进程挂起直到捕捉到一个信号。只有执行一个信号处理程序并从中返回时,pause 才返回。
/*
* 函数功能:设置进程的闹钟时间;
* 返回值:0或以前设置的闹钟时间余留的秒数;
* 函数原型:
*/
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
/*
* 说明:
* 参数seconds是秒数,经过指定的秒数seconds后会产生信号SIGALRM;
* 若进程之前登记过的闹钟尚未超过闹钟时间,而且本次seconds为0时,
* 则取消之前的闹钟时钟,其余留值仍作为alarm函数的返回值;
*/
int pause(void);//使调用进程挂起直到捕获到一个信号;
/*
* 只有执行了一个信号处理程序并从其返回时,pause才返回;
* 在这种情况下,pause返回-1,并将errno设置为EINTR;
*/
程序测试:
#include "apue.h"
#include <signal.h>
#include <unistd.h>
static void sig_alarm(int signo)
{
printf("Recevied alarm.\n");
}
static void sig_kill(int signo)
{
printf("Recevied kill.\n");
}
int main(void)
{
int nsecs = 5;
if(signal(SIGALRM, sig_alarm) == SIG_ERR)
return(nsecs);
signal(SIGHUP,sig_kill);
printf("kill()\n");
kill(getpid(),SIGHUP);
printf("alarm()\n");
alarm(nsecs);
printf("pause.\n");
pause();
printf("raise().\n");
raise(SIGHUP);
exit(0);
}
输出结果:
kill()
Recevied kill.
alarm()
pause.
Recevied alarm.
raise().
Hangup
参考资料:
《unix高级环境编程》