Linux进程间通信及信号讲解

一、背景说明

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

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

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

二、Linux信号种类

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

Signal NameSignal NumberDescription
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信号的办法

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信号忽略办法

符号 使用示例 作用 做不到
> 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

原文地址:https://www.cnblogs.com/lsdb/p/14252871.html