此代码打印捕获信号的 pid 和 uid:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
static void my_handler(int signum, siginfo_t *siginfo, void *context) {
FILE *f = fopen("sig_clog.txt", "a");
fprintf(f, "Got signal '%d' from process '%d' of user '%d'\n",
signum, siginfo->si_pid, siginfo->si_uid);
fclose(f);
}
int main(void) {
FILE *f = fopen("sig_clog.txt", "w");
fclose(f);
struct sigaction act;
memset(&act, '\0', sizeof(act));
act.sa_sigaction = &my_handler;
act.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &act, NULL);
sigaction(SIGTSTP, &act, NULL);
sigaction(SIGCONT, &act, NULL);
sigaction(SIGHUP, &act, NULL);
printf("Hi, my pid is %d\n", getpid());
printf("my parent pid is %d\n", getppid());
while(1)
sleep(1000);
return 0;
}
运行此命令后,如果我打开另一个终端并使用
kill
命令向该进程发送信号,它会写入一个 pid 和一个 uid (它们是一些随机数,我不确定它是否正确)。但是相反,如果我使用 Ctrl+C
中断,那么它会将 pid 和 uid 写为 0。 pid 0 的进程不是内核进程吗?我期望 pid 是 shell 的 pid。 shell 如何让内核向进程发送信号?为什么?
另外,除了
int
、tstp
和quit
之外,还有什么方法可以通过shell本身生成信号吗?或添加自定义信号键码?喜欢通过 Ctrl+K
发送 kill
信号吗?我看到了stty
命令选项,但没有找到。
没有PID 0。第一个PID是1,这是一个特殊的守护进程。
如果存在 PID 0 进程,则无法向其发送信号,因为
kill(0, signal)
意味着向调用进程的进程组的每个成员发送信号。
换句话说,
pid_t
值为 0,以及负值,在流程相关接口中都具有保留含义。
在这种情况下,
sig_pid
的零值表示信号不是由进程生成的。
TTY 信号由 TTY 子系统(内核中的代码)生成,而不是由特定进程生成。