进程
信号
参考 https://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html
进程间通信 --管道
参考
https://liwei.life/2016/07/18/pipe/
进程环境
c函数总是从main函数开始执行,调用main之前先调用一个特殊的启动例程,该启动例程从内核取得命令行参数和环境变量,然后运行main。
进程终止
有以下八种方式
exit 和 _exit 、_Exit函数都是正常终止一个进程,后面两个会立即进入内核,而exit则先执行一些清理工作。还涉及一个终止状态,即进程退出的退出状态,如exit(5)。
登记函数 atexit()
一个进程可以登记最多32个函数,由exit()自动调用。调用顺序和登记顺序相反,类似线程的cleanup_push和cleanup_pop函数。
但稍有不同就是进程只有注册,待用由exit()负责,不用pop。注意exit(0)和return 0效果是一样的。
上图为C程序启动和终止的过程。
环境表和环境变量
环境指针是一个二级指针。
环境字符串形式:name = value
除了获得变量值还有设置变量值。具体函数为 putenv 、setenv、unsetenv。具体查阅。
setjmp和longjmp
类似于goto,但是goto不能跨越函数,适用于局部跳转。而setjmp和longjmp主要用于嵌套出错中,比如A调用B,B调用C,C运行发生了一个非致命性错误需要从A重新运行,若逐层返回很麻烦,上面两个函数闪亮登场。
以下为示例,setjmp参数为特殊类型的jmp_buf。存放恢复栈状态的所有信息,longjmp第二个参数为返回值,区分不同的返回。
在这个情况下,有个很重要的问题需要去考虑,即哪些变量会恢复到以前。
C程序存储空间布局
正文段是CPU执行的机器指令部分,正文段可共享(如很多shell但共享一个正文段),正文段只读。
初始化和未初始化就看程序中对变量有没有赋初值,未初始化的也叫 bss段,一般初始化为0.
栈,自动变量以及函数调用所需保存的信息存放处。堆用来动态分配内存。
存储空间分配
进程控制
进程标识
ID为0的进程通常是调度进程,是内核一部分,不执行任何磁盘上程序,ID为1为init进程,自举过程后由内核调用。
fork
fork调用之后,子进程是父进程的副本,例如子进程获得父进程数据空间、堆和栈的副本,父子进程之间并不共享,但是一般共享正文段。