Linux上的多进程编程
第七章、Linux上的多进程编程
1.输出缓冲区和主函数参数
1. 主函数的参数
argc的参数个数就是argv(字符指针数组)的数组长度
只要用户执行程序,main方法默认至少接受一个参数,此参数就是执行程序的命令。
envp 就是一些环境变量的显示
2.输出缓冲区
用_exit(0);的时候,不会打印内容出来(啥都不打印),exit是正常打印(先5秒然后 helloworld)
_exit(0)不会刷新缓冲区中的内容,直接结束。
- 缓冲区存在的意义是什么?
为了提升程序执行的效率,写一次,刷新一次,输出一次,就是进行了从用户态到内核态的切换,而有了缓冲区后,就不用频繁的切换,减少了开销。
2.操作文件的系统调用:系统调用和库函数的区别
见4.5
4.进程创建-fork方法
1.fork方法的使用与特点
进程创建–fork()方法
fork之后,父子进程是并发执行的。
取掉/n---->放入缓冲区:(缓冲区会复制,4a4b)
3个A
先是调用一次,产生一个fork,fork调用成功返回0,产生的这个fork还会往后走,调用第二个fork,一共会有三个进程,所以3个A
pid_t fork(void);方法,在#include<unistd.h>头文件中
2.父子进程空间是否共享?
父子进程用的不是同一块空间
父进程、子进程的数据(全局,局部,堆区)
3.写时拷贝技术
子进程完了之后释放一部分,父进程完了再释放一部分
- 在Linux系统上malloc最多能申请多少空间?
- 有swap和没有swap一样吗?
4.父子进程对文件描述符的共享
4.1文件操作举例代码
4.2父子进程对于fork之前打开的文件描述符是否共享?
并发进行
fork之后,父子进程都会读取文件中的内容,进行打印,父子进程是相互影响的。
原因:子进程的PCB是复制父进程的(浅拷贝)
5.系统调用和库函数的区别
单次调用而言,系统调用的效率高(因为如果需要读入10个字节,系统调用只读10个,而库函数调用一次会调用很多)
整体而言,库函数的效率比系统调用效率高(系统调用库函数每次调用特定的数目,库函数会多调用,因此整体而言,减少了访问内核的次数)
系统调用的执行过程:
1.每一个系统调用都有唯一的一个与其对应的系统调用号
2.产生0x80中断:调用其对应的中断处理函数
3.通过eax寄存器的值,在内核的系统调用表中查找对应内核方法去调用
0x80是系统调用号,eax中保存系统调用号,然后通过eax中保存的系统调用号,去内核中在系统调用表中找到方法 ,然后实现方法,将返回值存在eax中,eax通过move指令,将eax中的值移动到fd上。
- 利用文件操作的系统调用实现普通文件的cp命令
cp -r 源文件 目的路径
附录附录:
5.僵死进程及处理方法
1.如何处理僵死进程(wait方法有缺陷)
waitpid 可以指定需要的pid
2.进程替换
main.c
test.c
运行结果
结论
- fork之前打开的文件,在子进程执行了exec之后还能不能通过文件描述符访问该文件?
进程替换的方式
库函数
系统调用
6.Linux信号的使用
1.信号的概念
2.修改信号的响应方式
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200907170214159.png#pic_cente r)
3.发送信号
7.进程间通信
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200908004244164.png?x-oss- process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTg5MzUyMw==,size_16,color_FFFFFF,t_70#pic_center)
1.管道
1.有名管道:半双工通讯(在使用时,数据的流向是单向的)
1.例子
maina.c
mainb.c
运行
2.练习
a.c
b.c
总结
2.无名管道:半双工
举例
2.信号量
1.概念
一个信号量有两个标识:
用户标识:键值-key值-》整型数字( 由用户指定,用户只需要保证需要同步的进程给相同的key值)
内核标识:类似于ID值-》整型数字
2.信号量的使用
1.封装
sem.h
sem.c
删除的是整个信号量集
2.利用信号量来完成两个进程之间的同步执行控制
2.1例题1 aabb/aaaabbbb(间接制约关系)
结果出错:
查找错误:这样可以查找已有的信号量集
错误来源:
1.要把已有的信号量删除
2.printf要在v操作之前,不然已经释放了,还没打印时候b进程使用,可能会先打印b,两个文件都要改哦
2.2例题2:输出为abc(直接制约关系)
思路:
修改代码
删除不需要改:删除的是信号量集
代码如下:
需要三个信号量如下:
B
C
编译
2.3.附
3.共享内存
1.特点:是最快的IPC
原理:
2.使用过程
用信号量做同步控制
先写出共享内存的代码
shmdt不是删除,只是断开连接
B
A和B的对比
4.消息队列
1.概念
利用消息队列的 内核对象的机制,使得几个进程来访问同一个消息队列
2.常用方法
3.使用举例
A
B
插播:查看队列的方式
删除消息队列的方式
4.总结
-s信号量 -q消息队列 -m共享内存