文章目录:
1.进程创建
此处主要讲 fork()函数 和 vfork()函数
1.1 fork()函数
fork()函数的一些基本概念我们在前面fork()函数中讲过,如不了解可点击查看,此次我们主要对上篇没有说到的fork()函数的内容进行补充说明
fork()函数
• 子进程是拷贝父进程的PCB的,子进程的大部分数据是来源于父进程的。 eg:内存指针(数据段,代码段),页表
• 父进程创建子进程成功之后,父子进程是独立的两个进程(进程的独立性),父子进程的调度取决于操作系统内核
• 进程是抢占式执行的,父子进程谁先运行是不确定的
• 写时拷贝
fork失败的原因:
• 系统中有太多的进程
使用top命令可查看系统中的进程数
• 实际用户的进程数超过了限制
使用 ulimit -a 命令可查看最大进程限制为7261
1.2 vfork()函数
父进程指向一个进程虚拟地址空间,父进程调用vfork()函数创建一个子进程也指向同一个进程虚拟地址空间,此时会出现压栈问题
• vfork()函数存在调用栈混乱的问题
• 解决方法:子进程先调用,子进程调用完毕之后,父进程再调用
2.进程终止
2.1 进程终止的场景
• 从main函数的return返回
情况1:代码执行完毕,结果正确
情况2:代码执行完毕,结果不正确
• 程序崩溃
2.2 进程常见的终止方法
正常终止(可以通过 echo $? 查看进程退出码)
• 从main函数的return返回
测试如下:
• 调用exit函数----库函数
void exit(int status); //status退出码
测试如下:
创建一个main函数写入exit函数,会发现函数运行到exit就结束,不会运行exit后面的代码
如果将代码改成如下,去掉hello后面的\n再次运行,会发现hello依旧可以运行出来
因为exit函数可以刷新缓冲区所以,有没有\n都如上代码的输出结果并没有影响
• 调用_exit函数----系统调用函数
void _exit(int status); //status退出码
测试如下:
创建一个main函数写入_exit函数,会发现函数运行到_exit就结束,不会运行_exit后面的代码
如果将代码改成如下,去掉hello后面的\n再次运行,会发现并不会有结果输出
那么为什么会出现如上的情况呢?
因为\n可以刷新缓冲区,没有\n,_exit函数并不能刷新缓冲区,所以没有结果输出
对比上面exit函数和_exit函数的运行结果会发现:
•