Linux上的多进程编程
- 第七章、Linux上的多进程编程
- 1.输出缓冲区和主函数参数
- 2.操作文件的系统调用:系统调用和库函数的区别
- 4.进程创建-fork方法
- 5.僵死进程及处理方法
- 6.Linux信号的使用
- 7.进程间通信
- 8.仿写bash以及命令
第七章、Linux上的多进程编程
1.输出缓冲区和主函数参数
1. 主函数的参数
argc的参数个数就是argv(字符指针数组)的数组长度

只要用户执行程序,main方法默认至少接受一个参数,此参数就是执行程序的命令。



envp 就是一些环境变量的显示

2.输出缓冲区

用_exit(0);的时候,不会打印内容出来(啥都不打印),exit是正常打印(先5秒然后 helloworld)
_exit(0)不会刷新缓冲区中的内容,直接结束。


- 缓冲区存在的意义是什么?
为了提升程序执行的效率,写一次,刷新一次,输出一次,就是进行了从用户态到内核态的切换,而有了缓冲区后,就不用频繁的切换,减少了开销。
2.操作文件的系统调用:系统调用和库函数的区别
见4.5
4.进程创建-fork方法
1.fork方法的使用与特点
3. 进程创建–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.修改信号的响应方式









3.发送信号










7.进程间通信



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共享内存











