一. 进程通信(IPC)概述
1.发展来源:UNIX进程间通信,基于System V进程间通信,POSIX(可移植操作系统接口)进程间通信
2.进程通信分类:信号、无名管道和有名管道、消息队列、共享内存、信号量、套接字
3.进程通信常用命令:
(1)ipcs:查看共享内存、信号量、消息队列
(2)ipcs -q(消息队列):只查看消息队列,同理:-m(共享内存)
(3)ipcrm -q + id :删除消息队列
二.信号signal通信(linux支持32种信号,9也就是SIGKILL信号最牛逼)
1.信号是在软件层次上对中断机制的一种模拟,信号是进程通信机制中唯一的异步通信机制
2.常见信号类型:kill -l 命令显示当前系统支持的所有信号
3.可靠信号与不可靠信号
(1)信号值小于SIGRTMIN的信号都是不可靠信号
(2)Linux下的不可靠信号问题主要指的是信号可能丢失
(3)可靠信号支持排队,不会丢失
(4)信号的可靠与不可靠只与信号值有关,与信号的发送和安装函数无关
(5)后32个信号表示实时信号,非实时信号都是不可靠信号,实时信号都是可靠信号
4.信号处理方式
(1)忽略信号,但是有两个信号不能忽略:SIGKILL(9)和SIGSTOP(19),因为他们向超级用户提供了一种终止或者停止进程的方法
(2)捕捉信号: 定义信号处理函数, 执行用户希望的动作,收到信号后,调用一个用户函数
(3)执行默认操作:Linux对每种信号都规定了默认操作,进程对实时信号的默认反应是进程终止
5.信号发送
(1)kill()函数或者kill命令:传送信号给指定的进程
(2)rasise():给自己进程发送信号
(3)alarm()函数:用于设置信号传送闹钟
6.自定义处理信号方式
(1)如果进程要处理某一信号,要在进程中安装该信号,即进程将要处理哪个信号,该信号被传递给进程时,将执行何种操作
(2)Linux主要由signal()函数实现信号的安装
三. 管道通信
1.管道是单向,先进先出的,一个管道用于两个进程,数据被一个进程读出后,将被从管道中删除,管道提供了简单的流控制机制,进程试图读空管道时,进程将堵塞,同样,管道满时,进程无法再写数据,管道的缺陷就是一个管道只能用于两个进程
2.无名管道pipe
无名管道用于父子进程间通信,是不可见的,当一个管道创建时,他会创建两个文件描述符,fd【1】用来写管道,fd【0】用于读管道
注意事项:必须在系统调用fork之前调用pipe,否则子进程将不会继承文件描述符
3.有名管道
(1)有名管道可用于运行于同一系统中的任意两个进程间的通信,一旦创建了一个FIFO,就可用open打开它,一般的文件访问函数都可用于FIFO
(2)建立有名管道参数会依参数pathname建立特殊的FIFO文件,该文件必须不存在,所以函数末尾调用unlink()函数用来删除文件
例题:用有名管道实现消息发送接收
发送端:
接收端:(不需要创建)
四.消息队列
1.管道只能传送无格式的字节流并且只能用于两个进程,消息队列客服了这些缺点,另外在成功的读取一条消息后,队列中的这条信息将被删除
2.消息队列操作:
1)创建(获取)消息队列:msgget()
2)发送/读取数据:msgsnd()和msgrcv()
3)删除消息队列:msgctl()
我们在这里实现一个多进程通信的互相发送的创建端,获取端负责获取并且不要初始化不要删除就OK了变化不大一个while循环里不能出现两个阻塞函数,所以我们用父子进程来实现
注意事项:定义数据一定放在while循环外面,接收端一定要加上杀死父进程,这样一个进程发送bye,四个进程就都结束了
- 共享内存
(1)共享内存时被多个进程共享的一部分物理内存,共享内存时进程间共享数据的一种最快的方法
(2)共享内存实现步骤:
1)创建(获取)共享内存:shmget()
2)映射共享内存:shmat()
3)使用内存:用strcpy或者地址往地址里面写东西
4)接触映射:shmdt()
5)删除映射:shmctl()
- 信号量(信号灯)
(1)信号灯主要用来保护临界资源,进程可以根据他判定是否能访问某些共享资源,除了用于访问控制外,还可用于进程同步
(2)分类:二值信号灯(信号灯的值只能取0或1,类似于互斥锁)、计数信号灯(信号灯的值为任意非负值)
(3)信号量操作步骤:
1)创建(获取)信号量:semget()
2)初始化:semctl()
3)pv操作:semop()
4)删除:semctl()
我们利用共享内存和信号量联合起来写个收发程序还是只实现发送端