1.终止进程的一般做法

在运行程序时要对某些程序进程进行终止操作,可以使用kill命令和对应的pid号进行处理,这种方法对于后台运行的程序特别有用:
ps -a 列出所有进程:

  PID TTY          TIME CMD
 3946 pts/20   00:23:11 python
 3523 pts/27   00:10:00 ps

或者使用管道来获取对应应用程序的进程号:

ps | grep python
3946 pts/20 00:13:55 python

随后就可以使用kill来关闭这一程序了:

kill -9 2946

但是,kill命令除了-9外还有很多的用途:

kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

2.kill 的sigspec的详细内容

在终端中输入kill -l会看到除了-9外还有很多其他的信号:

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

其中9是立即结束进程的信号不能被阻塞处理,而安全结束进程的信号可以使用SIGTERM(15),这个信号可以被阻塞处理。

需要注意的是:

默认情况下, killpkill命令发送的信号是SIGTERM(15) 。

kill -9pkill -9将发送SIGKILL信号。 不能捕获或忽略 SIGKILLSIGSTOP信号。

常用的Ctrl+C 发出的是SIGKILL信号。

3.如何捕捉

        signal 函数比较老了,功能有一些限制,现在常用的是 sigaction, 在信号处理程序中使用异步信号安全的函数。

int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

第一个参数为目标信号,第二个参数为sigaction结构,内有处理机制,信号掩码,和标志。

4.举个栗子

一段捕获SIGTERM并处理它的C代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include <signal.h>
#include <unistd.h>
 
#define SIGTERM_MSG "SIGTERM received.\n"
 
void sig_term_handler(int signum, siginfo_t *info, void *ptr)
{
    write(STDERR_FILENO, SIGTERM_MSG, sizeof(SIGTERM_MSG));
}
 
void catch_sigterm()
{
    static struct sigaction _sigact;
 
    memset(&_sigact, 0, sizeof(_sigact));
    _sigact.sa_sigaction = sig_term_handler;
    _sigact.sa_flags = SA_SIGINFO;
 
    sigaction(SIGTERM, &_sigact, NULL);
}
 
void main()
{
    catch_sigterm();
    printf("I am sleeping...\n");
    sleep(3000);
}

        可以更改上面这段代码以捕获不同的信号。 在VOLUME系统中 ,我们捕获SIGSEGV来捕获页面错误以实现分布式虚拟内存。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐