一个最简单的 golang 进程,比如
package main
import "time"
func main() {
time.Sleep(100000000*time.Second)
}
使用 kill -s PIPE 17033
命令,杀不死,这是为什么呢?
【结论:go的编译器对SIGPIPE等部分中断信号做了一些屏蔽处理,下面是长篇大论的验证,如果你有兴趣可以看一看,go的编译器实现很骚,是我见过最骚最不单纯的语言】
如果你以前写过进程间通信【管理,匿名管道,文件,SOCKET等】可能遇到过此中断信号SIGPIPE
如果你以前亲自写过网络编程 可能对SIGPIPE中断信号非常熟悉
中断信号 简称软中断,它的处理机制跟硬件中断类似,有中断请求,中断处理【处理过程有的称为中断处理程序,中断处理函数,比如你写过网络编程就知道 网卡接收到数据时,会发起中断请求到CPU,CPU执行中断处理程序,就会把数据写入到对应的SOCKET 文件,比如EPOLL 文件,同时唤醒进程执行 SOCKET的读写操作】中断处理完以后,就会返回到原处,称为中断返回,整个过程就是中断的处理机制。
在LINUX 中可以通过kill命令列出所有的中断信号,每个信号都以SIG开头,后面就是中断的名字,前面的数值就是中断信号的编号。最常用的就是前面的32个。
每个中断信号都有相应的中断处理程序【处理函数】默认有3种类型的【1是系统默认动作,2是忽略 3是用户编写的中断处理程序】
中断信号除了用于进程间的简单通信,还能让进程终止,停止,恢复执行【如进程作业控制】,有些信号进程可以忽略,捕获,有些信号进程不能忽略和捕获,主要用于安全的确保终止和停止如SIGKILL,SIGSTOP
同时有些中断信号还能产生ELF 文件即core 文件并终止。
给进程发送信号除了编程语言封装的如php posix_kill,c/c++则是kill,但都是用linux api的kill
而终端命令如kill就是用来发送中断信号的,并不是所谓的“杀死”
进程可以设置屏蔽字设置阻塞的中断信号,当中断信号产生请求时,会被阻塞,并存储在未决集里
中断信号还能影响到系统调用,如果你写过网络编程,或是你了解网络框架,了解网络通信协议如HTTP,WEBSOCKET等,你会发现一个东西叫 “中断系统调用”或是你掌握网络编程时,必须知道“中断系统调用” 和 “可重入函数” 如IO复用函数select,epoll都是中断系统调用。
中断信号的掌握是一个程序员掌握网络编程的一个关键知识点。
更多知识点请自行阅读LINUX API 手册 或是@ me
以上知识跟编程语言没有任何关系!!!
下面恢复测试你的程序
go文件补充【我不是学go语言的,因为这些知识跟语言没有任何关系】
文件类型,只是一个文本文件,你们称为go源码文件
在控制终端进程下启动go程序
查看是何命令启动的:
查看进程关联了哪个输入输出文件
里里有epoll文件和2个管道文件【google闲的没事干了】
上面这些内容是什么意思?
看完上面的图,你就知道go的实现机制很骚,并不是启动一个进程,而启动一堆进程和线程
接下来我们用c程序测试SIGPIPE 中断信号
执行信号的默认动作 SIGPIPE
因为你没有处理 默认忽略