进程通信
一、概念
进程通信是进程进行通信和同步的机制
基本操作
发送操作:send(message)
接受操作:receive(message)
进程通信流程
①在通信进程间建立通信链路
②通过send/receive交换信息
通信方式:间接通信和直接通信
1.直接通信
进程必须正确地命名对方进程
send(P,message) P为接收方进程
receive(Q,message) Q为发送方进程
通信链路的属性
- 自动建立链路
- 一条链路对应一对通信进程
2.间接通信
通过操作系统维护的消息队列实现进程间的消息接受和发送
send(A,message) 发送消息到消息队列A
receive(A,message) 从消息队列A中接受消息
通信链路的属性
- 每个消息队列都有唯一的标识
- 只有共享了相同消息队列的进程,才能通信
- 消息队列可以与多个进程相关联
- 每对进程可以共享多个消息队列
3.阻塞通信和非阻塞通信
阻塞通信(同步)
阻塞发送:发送者在发送消息后进入等待,直到有接受者成功收到消息
阻塞接受:接受者在请求接受消息后进入等待,直到成功收到消息
非阻塞通信(异步)
非阻塞发送:发送者在消息发送后,可立即进行其他操作
非阻塞接受:没有消息发送时,接受者在请求接受消息后接受不到任何消息
4.通信链路缓冲
- 0容量:发送方必须等待接收方
- 有限容量:通信链路缓冲队列满时,发送方必须等待
- 无限容量:发送方不许等待
5.四种通信机制
信号、管道、消息队列、共享内存
二、信号
进程间的软件中断和处理机制(SIGKILL、SIGSTOP、SIGCONT等)
不足:传送的信号量小、只有一个信号类型
void sigproc(){
signal(SIGINT,sigproc);
printf("you have pressed ctrl-c \n");
}
main(){
signal(SIGINT,sigproc);
for(;;);
}
三、管道
进程基于内存文件的通信机制
- 子进程从父进程继承文件描述符
- 缺省文件描述符:0 stdin、1 stdout、2 stderr
- 进程不知道另一端的情况(可能从键盘、文件、程序读取,可写入终端、文件、程序)
与管道相关的系统调用
- 读管道:read(fd,buffer,nbytes) scanf()是基于它实现的
- 写管道:write(fd,buffer,nbytes) print()是基于它实现的
- 创建管道:pipe(p)
3.1. p是2个文件描述符组成的数组
3.2. p[0]是读文件描述符
3.3. p[1]是写文件描述符
四、消息队列
消息队列是由操作系统维护的以字节序列为基本单位的间接通信机制
- 每个消息是一个字节序列
- 相同标识的消息按先进先出顺序组成一个消息队列
msgget(key,flags) 获取消息队列标识
msgsnd(QID,buf,size,flags) 发送消息
msgrcv(QID,buf,size,type,flags) 接受消息
msgctl() 消息队列控制(创建、删除等)
五、共享内存
共享内存是把同一个物理内存区域同时映射到多个进程的内存地址空间的通信机制
对于进程
- 每个进程都有私有内存地址空间
- 每个进程的内存地址空间需明确设置共享内存段
对于线程
- 同一进程的线程总是共享相同的内存地址空间
优点:快速、方便地共享数据
缺点:必须额外的同步机制来协调数据访问
shmget(key,size,flags) 创建共享段
shmat(shmid,*shmaddr,flags) 把共享段映射到进程地址空间
shmdt(*shmaddr) 取消共享段到进程地址空间的映射
shmctl() 共享段控制