目录
进程创建
调用fork后系统会做什么?
所以,fork之前父进程独立执行,fork之后,父子两个执行流分别执行。
注意,fork之后,谁先执行完全由调度器决定。
写时拷贝
通常,父子代码共享,父子不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。
数据权限问题
如果你是只读数据那么权限还是只读,如果你是可读写那么第一次权限改成暂时的只读,当你要写入时,遇到暂时的只读会触发写时拷贝,并且把这个暂时的只读改为可读写。
为什么要写时拷贝?
从技术上讲,当你创建子进程时,父进程完全可以把代码和数据全部拷贝过去,但万一需要写入的数据只有少数,剩下的数据只需要读取,这样相当于有大量重复内容,造成空间浪费,所以写时拷贝是一种按需申请,等你要用时再给你进行拷贝写入。
进程终止
进程终止的三种情况,结果不正确我们需要知道为什么不正确。
main函数的返回值
退出码
这个返回值会被父进程拿到,因为父进程会关心子进程的运行情况,结果不正确可以用不同的数字表示不同的原因,这个数字叫退出码。
$?
$?:保存最近一次进程的退出码。
第一次是某个程序退出,第二次就是echo。
strerror
strerror查看错误码描述。不同的错误码有对应的错误码描述。
所以代码运行完,用进程的退出码判断结果是否正确,也就是main的返回值。
errno
返回最近一次的错误码
代码异常终止
异常终止后退出码就无意义了,所以我们先看有没有异常终止再看退出码。
进程出现异常本质是收到了对应的信号。
进程终止的方法
exit
12是当前进程的退出码。
exit表示进程直接退出,比如main调了一个函数,这个函数里面有exit,那么函数走到exit之后,会直接把main退出。如果函数里面是return,那么只是返回到main里面。
return在其他函数表示函数返回,在main函数表示进程退出。
exit在任意位置都表示进程退出。
_exit
是一个系统调用,退出时不会刷新缓冲区,因为这个缓冲区不在内核中。