kill函数将信号发送给进程或进程组。raise函数则允许进程向自身发送信号。

raise最初是由ISO C定义的。后来,为了与ISO C标准保持一致,POSIX.1也包括了该函数。但是POSIX.1扩展了raise的规范,使其可处理线程(12.8中讨论线程如何与信号交互)。

因为ISO C并不涉及多进程,所以它不能定义以进程ID作为其参数(如kill函数)的函数。

#include <signal.h>
int kill(pid_t pid, int signo);
int raise(int signo);
//两个函数返回值:若成功,返回0;若出错,返回−1

调用

raise(signo);

等价于调用

kill(getpid(), signo);

kill的pid参数有以下4种不同的情况。

  • pid > 0 将该信号发送给进程ID为pid的进程。
  • pid == 0 将该信号发送给与发送进程属于同一进程组的所有进程(这些进程的进程组 ID等于发送进程的进程组 ID),而且发送进程具有权限向这些进程发送信号。

?: 这里用的术语“所有进程”不包括实现定义的系统进程集。对于大多数UNIX系统,系统进程集包括内核进程和init(pid为1)。

  • pid < 0 将该信号发送给其进程组ID等于pid绝对值,而且发送进程具有权限向其发送信号的所有进程。如前所述,所有进程并不包括系统进程集中的进程。
  • pid == −1 将该信号发送给发送进程有权限向它们发送信号的所有进程。如前所述,所有进程不包括系统进程集中的进程。

如前所述,进程将信号发送给其他进程需要权限。超级用户可将信号发送给任一进程。对于非超级用户,其基本规则是发送者的实际用户 ID 或有效用户 ID 必须等于接收者的实际用户 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为调用进程产生信号,而且此信号是不被阻塞的,那么在kill返回之前, signo或者某个其他未决的、非阻塞信号被传送至该进程。(对于线程而言,还有一些附加条件;详细情况见12.8节。)

results matching ""

    No results matching ""