进程间能共享或传递数据就算是进程间通信。
IPC机制 | 含义 | 通信方式 |
---|---|---|
信号 (Signal) | 异步发送信号给进程处理 | 间接通信 |
管道 (Pipe) | 单方向传输字节流 | 间接通信 |
消息队列 (Message Queue) | 通过队列中转收/发消息 | 间接通信 |
套接字 (Socket) | 多/单机进程间网络通信 | 间接通信 |
共享内存 (Shared Memory) | 多个进程共享一块物理内存 | 直接通信 |
文件 (File) | 多个进程可访问同一文件 | 间接通信 |
进程间能共享或传递数据就是进程间通信。
Remote Procedure Call, RPC = send + recv
提纲
管道是一种进程间通信机制, 也称为匿名管道(anonymous pipe)
int pipe(int pipefd[2])
$ gcc -o ex1 ex1.c
$ ./ex1
parent
write: the 0 message.
write: the 1 message.
...
children
read: the 0 message.
read: the 1 message.
...
建议:同学们可在课后在自己的开发环境中实践一下
只需使用一根竖线 "|" 连接两个命令即
rCore-Tutorial-v3 on ch7
❯ cat README.md | grep rcore
$ git clone https://github.com/rcore-os/rCore-Tutorial-v3.git
...
* [x] expand the fs image size generated by `rcore-fs-fuse` to 128MiB
在shell中可用mkfifo命令创建命名管道,也称为FIFO。
匿名管道与命名管道都属于单向通信机制。两者的不同是:
命名管道是阻塞式的单向通信管道
shell A
$ mkfifo name.fifo
$ echo README > name.fifo #文件类型为p,写命名管道阻塞
shell B
$ cat name.fifo
但:字节流形态,不支持任意两个进程间的双向通信
命名管道示例
提纲
消息队列是由操作系统维护的以结构数据为基本单位的间接通信机制
消息的结构
struct msgbuf {
long mtype; /* 消息的类型 */
char mtext[1]; /* 消息正文 */
};
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
参数:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
返回值:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
那么如何获取key值?
int msgsnd(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
参数:
int msgsnd(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
int msgrcv(int msgid, void *msg_ptr, size_t msgsz,long int msgtype, int msgflg);
int msgrcv(int msgid, void *msg_ptr, size_t msgsz,long int msgtype, int msgflg);
返回值:
$ gcc ex1.c
$ ./a.out
Parent: input message type:
1
Parent: input message to be sent:
test
Parent: input message type:
Child: read msg:test
0
建议:同学们可在课后在自己的开发环境中实践一下
提纲
共享内存是把同一个物理内存区域同时映射到多个进程的内存地址空间的通信机制
注:需要信号量等同步机制协调共享内存的访问冲突
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
将一个共享内存段映射到调用进程的数据段中。即:让进程和共享内存建立一种联系,让进程某个指针指向此共享内存。
返回值:
void *shmat(int shmid, const void *shmaddr, int shmflg);
$ gcc writer.c -o w
$ gcc reader.c -o r
$ ./w
Writer: copy data to shared-memory
$ ./r
------------ 共享内存段 --------------
键 shmid 拥有者 权限 字节 连接数 状态
0xdf20482b 1 chyyuu 666 512 0
data = [ How are you, mike: from Writer ]
deleted shared-memory
------------ 共享内存段 --------------
键 shmid 拥有者 权限 字节 连接数 状态
建议:同学们可在课后在自己的开发环境中实践一下
提纲
问题:
Ctrl+C
为什么可以结束进程?Linux有哪些信号? -- 62个
为什么这么多信号?
https://zhuanlan.zhihu.com/p/268389190 Linux进程间通信——消息队列
https://zhuanlan.zhihu.com/p/147826545 Linux系统编程之进程间通信:共享内存
Ref: Understanding the Linux Kernel Signals and Inter-Process Communication https://compas.cs.stonybrook.edu/~nhonarmand/courses/fa14/cse506.2/slides/ipc.pdf