复习(基础I/O):
● 动态库与静态库的生成与使用:(.c文件编译生成目标代码)
Gcc -fPIC(动态库编译) -c child.c -o child.o
● 链接打包成库文件
动态库:gcc –share child.o -o libchild.so
(–share 说明生成动态库)
静态库:ar -cr libchild.a child.o
● 链接使用:
Gcc main.c -o main -lchild
- 将库文件放在指定的路径下
/lib64 /usr/lib64
- 设置环境变量
LIBRARY_PATH
gcc -L
选项指定一下库文件 所在路径(常用)
● 运行使用:主要针对动态库;静态库运行时已经放入可执行程序中,不需要依赖库文件。
- 将库文件放在指定的路径下
/lib64 /usr/lib64
- 设置环境变量
LD_LIBRARY_PATH
进程间通信
● 进程间通信:IPC—操作系统为用户提供的几种进程间通信方式
- 操作系统为用户提供的几种进程间通信方式
- 主要是因为进程间具有独立性(每个进程操作的都是自己的虚拟地址空间)
- 因为通信场景不同,提供了不同的方式
● WHY:操作系统要提供进程间通信方式给用户?
- 答:因为进程之间具有独立性(每个进程只能访问自己的虚拟地址)
无法直接进行沟通,因此需要操作系统提供公共的媒介。
通信场景:数据传输;数据共享;进程控制
标准:System V标准/posix 标准
通信方式分类:管道,共享内存,消息队列,信号量
管道:用于进程间的数据传输
● 本质:是内核中的一块缓冲区;多个进程通过访问同一块缓冲区实现通信
● 分类:匿名管道/命名管道
● 特性
- 管道是半双工通信,可以选择方向的单向通信
- 管道的生命周期随进程
- 管道自带同步与互斥(读写特性的体现)
- 管道提供字节流传输服务
● 匿名管道:缓冲区没有标识符,只能通过子进程复制父进程的方式获取到管道的操作句柄(文件描述符)
头文件:include<unistd.h>
接口:int pipe(int pipefd[2]); ==》int pipefd[2]; pipe(pipefd);
参数:int pipe(int pipefd[ 2 ])
;两个int型元素数组的首地址。
- Pipefd[0]:用于从管道读取数据
- Pipefd[1]:用于向管道写入数据
返回值: 0 成功; -1 失败
特性:只能用于具有亲缘关系的进程间通信(创建管道一定要放在创建子进程之前)
操作句柄:两个文件描述符,一个用于读取数据,一个用于向管道写入数据。
实现原理: 一个进程通过系统调用在内核中创建了一个管道(缓冲区),并且调用返回管道的操作句柄。但是,内核中的这块缓冲区没有其他标识符,只能通过操作句柄访问;因此匿名管道只能用于具有亲缘关系的进程间通信,因为只能通过子进程复制父进程的方式获取到同一个管道的操作句柄,进而访问同一块缓冲区。
读写特性:
- 管道中没有数据,则read读取数据会阻塞,直到有数据。
- 管道中数据写满,则write继续写入数据会阻塞,直到有数据被读出去(腾出空间)。
- 若管道的所有写端被关闭,则read读完管道数据后,不会阻塞,而是返回0。
当read返回0的时候表示,管道已经没人写了,继续读已经没有意义。 - 若管道所有读端被关闭,则write写入数据时,会触发异常,进程退出
操作原子性:这个操作不会被打断,可用于实现互斥。
互斥与同步
- 互斥:同一时间只有一个执行流能够操作临界资源,实现数据的安全操作----保证数据的操作安全性。
- 同步:通过一种条件的判断,来实现对临界资源访问的时序合理性
匿名管道的应用
|:管道符,连接两个命令,将前面命令的输出结果交给后面命令进行处理。
● 命名管道:内核中这块缓冲区有一个标识符,这个标识符是一个可见于文件系统的管道文件。
特性:可用于同一主机上的任意间通信 (打开特性是命名管道所独有的)
- P:管道文件 l:符号链接 d:目录文件 -:普通文件
b:扩设备文件 c:字符设备文件 s:socket文件
读写特性:
- 若命名管道以只读方式打开,则会阻塞直到管道文件被其他进程以写的方式打开
- 若命名管道以只写方式打开,则会阻塞直到管道文件被其他进程以读的方式打开
● 匿名VS命名管道
- 匿名:只能用于具有亲缘关系的进程间通信(没有标识符)
- 命名:可用于任意同一主机进程间通信(标识符是一个管道文件)
共享内存:用于进程间的数据共享
特性:最快的进程间通信方式
实现原理:
- 在物理内存中开辟一块空间—这块空间在内核中是具有标识的
- 将这块空间通过页表映射到自己的虚拟地址空间中
- 通过虚拟地址进行内存操作
- 解除映射关系
- 删除共享内存
原理:共享内存相较于其他进程间通信方式,在通信过程中,少了两次用户态与内核态之间的数据拷贝
● Ipcs指令:用于查看系统上进程间通信方式。
消息队列:用于进程间的数据块传输
本质:内核中的一个优先级队列,多个进程通过向同一个队列中放置队列节点或获取节点实现通信。
实现原理:
- 在内核中创建消息队列
- 向队列中添加节点
- 从队列中获取节点
- 删除消息队列
特性: - 消息队列自带同步与互斥
- 传输有类型的数据块
- 数据不会粘连
- 生命周期随内核
现状:几乎被淘汰;因为它限制的比较多,限制队列中所能放置的最大数据大小,无法去动态改变
分析步骤:实现----》特性-----》应用------》原理