Linux进程间通信方式简要

在Linux中,使用进程之间通过多种方式进行通信,包括管道、信号、共享内存、消息队列、套接字等。进程间通信实现不同进程之间的数据共享和协作,更好完成各自任务。

管道 - pipe

比如ls | grep 123 中,就将ls这个进程的输出,作为grep的输入进行传递。

信号 - signal

一个进程,可以向另一个进程发送信号,并且另一个进程可以去处理这个发送来的信号。

共享内存 - shard memory

共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。

消息队列 - message queues

消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

信号量 - semaphores

信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

套接字 - socket

套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。例如访问远端的MySQL服务器,需要注意,如果MySQL服务在本地,则套接字使用的unix套接字,而非tcp套接字。


列出所有的信号类型

可能会有疑问,为什么是kill,因为在linux当中,大部分信号都是将进程给杀死,所以干脆就统一称为kill了。64种死法。

1
2
kill -l
HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2

如何终止一个进程

1
2
px -aux | grep xxx # 通过进程名等获取进程pid
kill -9 111 # 给pid为111的进程发送sigkill信号

在程序开发过程中,可以让程序捕捉并处理kill进程发送来的信号。 但是有个约定俗成的约定,kill -9信号,也就是sigkill信号是不可以被捕捉并处理的,即程序接收到kill -9信号,则必须得死。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
	done := make(chan bool, 1)

	go func() {
		sig := <-sigs
		fmt.Println()
		fmt.Println(sig)
		done <- true
	}()

	fmt.Println("awaiting signal")
	<-done
	fmt.Println("exiting")
}

img_1.png