分类: 系统运维
2012-03-30 19:15:54
kill函数发送一个信号给一个进程或一个进程组。raise函数允许一个进程给它自己发送一个信号。
raise最开始被ISO C定义。POSIX.1包含了它来与ISO C标准靠齐。但是POSIX.1扩展了raise的规范来处理线程(我们在12.8节讨论线程如何与信号交互。)因为ISO C不处理多进程,它不能定义一个需要一个进程ID参数的函数,比如kill。
调用raise(signo)等价于kill(getpid(), signo);
kill的pid参数有四种情况:
1、pid > 0,信号被发送给进程ID为pid的进程;
2、pid == 0,信号被发送给与发送者同组、且发送者对其有发送信号的权限的所有进程。注意术语“所有进程”不包括实现定义的系统进程集。对于多数UNIX系统,这个系统进程集包括内核进程和init(pid 1);
3、pid < 0,信号被发送给ID为pid的绝对值的进程组里的,且发送者对其有发送信号的权限的所有进程。再次,所有进程集不包括系统进程,如上所述。
4、pid == -1,信号被发送给系统上发送者对其有发送信号的权限的所有的进程。和前面一样,不包含特定的系统进程。
正如我们已经提到的,一个进程需要权限来发送信号给另一个进程。超级用户可以发送一个信号给任何进程。对于其它用户,基本规则是发送者的真实或有效用户ID 必须等于接收者的真实或有效的用户ID。如果实现支持_POSIX_SAVED_IDS(如POSIX.1现在要求的),那么接收者的设置用户ID被核 查,而不是它的有效用户ID。权限测试还有一个特殊的例子:如果被发送的信号是SIGCONT,那么一个进程可以把它发送给相同会话里的任何其它进程。
POSIX.1 定义信号号0作为空信号。如果signo参数为0,那么kill会执行普通的错误检查,但是没有信号被发送。这通常用来检查一个特定进程是否仍存在。如果 我们给进程发送一个空信号而它不存在,那么kill返回-1而errno被设为ESRCH。但是要小心,UNIX系统在一些时间后会回收进程ID,所以一 个给定进程ID的进程的存在性不表示它就是你认为的那个进程。
还要理解进程存在性的测试不是原子的。在kill返回回答给调用者的时候,被查询的进程可能已经退出了,所以这个回答的价值有限。
如果kill调用导致信号为调用进程产生且信号没有被阻塞,那么signo或其它待定的非阻塞的信号被发送给进程,在kill返回之前。(对于线程有其它的情况,12.8节。)