一、fork函數
Linux系統中創建進程需要消耗較大資源,所以使用fork函數生成一個子進程,子進程的PCB(進程控制塊)會復制父進程的數據!
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("%d\n", getppid());
pid_t p1 = fork();
if(p1 > 0)
{
//父進程
printf("parent pid = %d, p1 = %d\n", getpid(), p1);
}
else
{
//子進程
printf("son pid = %d , ppid = %d, p1 = %d\n", getpid(), getppid(), p1);
}
return 0;
}
這是fork的簡單應用,在運行fork()就生成了了一個子進程,父子進程運行的代碼是相同的!fork之后的代碼在兩個進程中運行!
所以fork函數會在父子進程中分別返回,在父進程中返回子進程的pid,而在子進程中會返回0!所以可以根據判斷在父子進程中運行不同的代碼!
二、僵屍進程和孤兒進程
在進程結束后,Linux系統會自動回收進程消耗的 內存和IO,但是進程本身占用的資源(task_struct和棧內存)不會被回收,需要被父進程來進行回收
(1)僵屍進程
子進程比父進程先結束!
如果父進程沒有顯示調用wait或waitpid函數的話,會直到父進程結束時才會回收子進程的資源!這樣的子進程,就是僵屍進程!
(2)孤兒進程
父進程先於子進程結束,子進程於是成為進程1(init進程)的子進程,直到關機才會回收!
三、wait函數
wait函數原型為 pid_t wait(int *status);
當父進程調用wait時會被阻塞住,直到收到子進程的SIGCHLLD信號,就會回收相關資源!
@return f返回被回收的子進程的pid
@param status 這個地址將會被賦值,可以通過一些宏來判斷結束狀態!
四、文件讀寫
當父進程在fork之前打開的文件的文件,文件描述符維護的結構體也被復制,但是父子進程之間的文件描述符對應的文件指針相互關聯!
類似不同進程使用O_APPEND打開文件類似!
但是由於父子進程運行速度的原因,可能有一方還沒寫就被另一方關閉!
