一、背景说明

已经记不得最早听说Linux进程之间通过信号进行通信是什么时候了,但这个东西没次听完看完之后都不是很在意,感觉和自己平时使用没什么关系。

最近突然认识到这个结论其实很重要:Linux的进程间在没有人为给他们搭建通信通道时,他们间的通信(或者叫相互作用)都是且只能是通过发送信号进行。

比如除了经典的kill命令杀除进程是给目标进程发送信号,像Ctrl+C这种能影响进程状态的命令也都是给当前进程发送信号。

 

二、Linux信号种类

常见linux信号如下,可使用"man 7 signal"查看更多信号说明:

Signal Name

Signal Number

Description

SIGHUP

1

Hang up detected on controlling terminal or death of controlling process

SIGINT

2

Issued if the user sends an interrupt signal (Ctrl + C)

SIGQUIT

3

Issued if the user sends a quit signal (Ctrl + D)

SIGFPE

8

Issued if an illegal mathematical operation is attempted

SIGKILL

9

If a process gets this signal it must quit immediately and will not perform any clean-up operations

SIGALRM

14

Alarm clock signal (used for timers)

SIGTERM

15

Software termination signal (sent by kill by default)

 

简单的,可以使用“kill -l”列出:

linux发送ffpmeg命令java线程池 linux发送信号给进程_bash

 

三、给某进程发送Linux信号的办法

ctrl+c----向进程发出SIGINT信号

ctrl+d----向进程发出SIGQUIT信号

ctrl+z----向进程发出SIGHUP信号

kill -[s] Signal Name/Signal Number pid----向进程发送各种信号,有没有-s、是信号名还是信号值效果都是一样的。

 

四、Linux信号主动捕获办法

在bash中可以使用trap命令来捕抓信号,格式为"trap 捕获信号后想要执行的命令 信号"。示例如下:

# 定义一函数,该函数用作后边trap的响应函数
# 这里的意思是只有累计接收到三次Ctrl+C(亦即SIGINT信号)时才中断退出
ctrlc_count=0
function no_ctrlc()
{
    let ctrlc_count++
    echo
    if [[ $ctrlc_count == 1 ]]; then
        echo "Stop that."
    elif [[ $ctrlc_count == 2 ]]; then
        echo "Once more and I quit."
    else
        echo "That's it.  I quit."
        exit
    fi
}

# 捕获向本进程发送的SIGINT信号,并用no_ctrlc命令(即前边定义的函数)响应
# trap命令一是不另启进程,二是能正常捕抓信号,三是不会阻塞影响正常业务
# 具体原理我还不确定,但从效果看像是另启了一个线程来捕获信号
trap no_ctrlc SIGINT

# 正常的业务逻辑写在下边,我们这里随便写一个死循环

while true
do
    echo Sleeping
    sleep 10
done

View Code

运行截图如下,可以看到和预期一至:业务正常运行(sleep)、Ctrl+C产生的SIGINT被捕获且捕获到三次后进程退出:

linux发送ffpmeg命令java线程池 linux发送信号给进程_bash_02

 

五、Linux信号忽略办法

符号

使用示例

作用

做不到

>

bash test.sh > test.log

重定向输出

不占用当前控制台

不处理父进程退出信号

&

bash test.sh &

不占用当前控制台

重定向输出

不处理父进程退出信号

nohup

nohup bash test.sh

不处理交进程退出信号

随意重定向输出

不占用当前控制台

组合

nohup bash test.sh 2>&1 > test.log

 

 

 

 

参考:

https://www.linuxjournal.com/content/bash-trap-command