加粗样式

在linux中fork函数是⾮常重要的函数,它从已存在进程中创建⼀个新进程。新进程为⼦进程,⽽原进程为⽗进程。
#include <unistd.h>
pid_t fork(void);
返回值:⾃进程中返回0,⽗进程返回⼦进程id,出错返回-1进程调⽤fork,当控制转移到内核中的fork代码后,内核做:

当⼀个进程调⽤fork之后,就有两个⼆进制代码相同的进程。⽽且它们都运⾏到相同的地⽅。但每个进程都将可以开始它们⾃⼰的旅程,看如下程序。

这⾥看到了三⾏输出,⼀⾏before,两⾏after。进程43676先打印before消息,然后它有打印after。 另⼀个after消息有1398691打印的。注意到进程1398691没有打印before,为什么呢?如下图所⽰

所以,fork之前⽗进程独⽴执⾏,fork之后,⽗⼦两个执⾏流分别执⾏。注意,fork之后,谁先执⾏完 全由调度器决定。
通常,⽗⼦代码共享,⽗⼦再不写⼊时,数据也是共享的,当任意⼀⽅试图写⼊,便以写时拷⻉的⽅式各⾃⼀份副本。具体⻅下图:

因为有写时拷⻉技术的存在,所以⽗⼦进程得以彻底分离离!完成了进程独⽴性的技术保证!
写时拷⻉,是⼀种延时申请技术,可以提⾼整机内存的使⽤率
进程终⽌的本质是释放系统资源,就是释放进程申请的相关内核数据结构和对应的数据和代码。
正常终⽌(可以通过 echo $? 查看进程退出码):
异常退出:
退出码(退出状态)可以告诉我们最后一次执行的命令的状态。在命令结束以后,我们可以知道命令是成功完成的还是以错误结束的。其基本思想是,程序返回退出代码0时表示执行成功,没有问题。
代码1或 0以外的任何代码都被视为不成功。
Linux Shell 中的主要退出码 :
退出码 | 解释 |
|---|---|
0 | 命令成功执行 |
1 | 通用错误代码 |
2 | 命令(或参数)使用不当 |
126 | 权限被拒绝(或)无法执行 |
127 | 未找到命令,或PATH错误 |
128 + n | 命令被信号从外部终止,或遇到致命错误 |
130 | 通过Ctrl + C或SIGINT终止(终止代码2或键盘中断) |
143 | 通过SIGTERM终止(默认终止) |
255/ * | 退出码超过了0 - 255的范围,因此重新计算(LC3TT注:超过255后,用退出码取模) |
0表示命令执行无误,这是完成命令的理想状态。#include <unistd.h>
void _exit(int status);
参数:status 定义了进程的终⽌状态,⽗进程通过wait来获取该值说明:虽然status是int,但是仅有低8位可以被⽗进程所⽤。所以_exit(-1)时,在终端执⾏$?发现返回值是255。
#include <unistd.h>
void exit(int status);exit最后也会调⽤_exit,但在调⽤_exit之前,还做了其他⼯作:

实例:
int main()
{
printf("hello");
exit(0);
}
运⾏结果: [root @localhost linux] #./a.out
hello[root @localhost linux]#
int main()
{
printf("hello");
_exit(0);
}
运⾏结果:
[root @localhost linux] #./a.out
[root @localhost linux] #return是⼀种更常⻅的退出进程⽅法。执⾏returnn等同于执⾏exit(n),因为调⽤main的运⾏时函数会将main的返回值当做exit的参数。