发出信号并杀死 C

Signal and kill C

我正在了解 signal() 并且我有这两个文件:

server.c:

void handler_sigcont(){
  printf("SIGCONT server\n");
}

int main(){
  signal(SIGCONT,handler_sigcont);
  printf("%d\n",getpid());
  kill(getpid(),SIGSTOP);
  printf("server!\n");
}

client.c:

int main(int argc, char** argv){
  kill(atoi(argv[1]),SIGCONT);
  printf("client!\n");
}

首先我执行server.c,这是输出:

6999

[7]+  Stopped                 ./sobusrv

然后我像这样执行client.c:

./client 6999

唤醒进程6999。 输出如下:

client!
SIGCONT server
server!
[8]   Done                    ./sobusrv

但是,如果在 server.c 中,我将 kill() 之后的 signal() 更改为:

void handler_sigcont(){
  printf("SIGCONT server\n");
}

int main(){

  printf("%d\n",getpid());
  kill(getpid(),SIGSTOP);
  printf("server!\n");
  signal(SIGCONT,handler_sigcont);
}

我得到这个输出:

client!
server!
[8]   Done                    ./sobusrv

我想知道为什么在kill()后面写signal()时handler被回避了。

没有避免,只是操作顺序不同而已。在您注册处理程序之前,您的服务器会收到一个停止信号。当您向它发送 SIGCONT 时,它会继续,然后注册处理程序并退出,而不会收到另一个信号。对于注册处理程序之前发生的信号,将不会执行处理程序。

当在您的服务器中 kill() 之后写入对 signal() 的调用时,这意味着在服务器接收到 SIGCONT 之后才会安装信号处理程序。这是因为服务器中的kill()调用立即生效,挂起服务器进程。

在服务器收到 SIGCONT 时,将使用默认处理程序,因为尚未安装其他处理程序。

你可以像这样使用 raise(SIGCONT) 函数:

void handler_sigcont(int sig){
  printf("SIGCONT server\n");
}

int main(){
  signal(SIGCONT,handler_sigcont);
  printf("%d\n",getpid());
  raise(SIGCONT);
  printf("server!\n");
}