1. 進程創建
#include <sys/types.h>#include <unistd.h>pid_t fork(void);
????????fork? ?創建一個新進程
????????fork() ?creates ?a ?new process by duplicating the calling process. ?The new process is referred to as the child process. ?The ?calling ?process ?is ?referred to as the parent process.
? ?fork()
?通過復制調用進程來創建一個新進程。新創建的進程稱為子進程,而調用進程稱為父進程。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>int main() {pid_t pid = fork();if (pid == 0) {/*在父進程中,子進程的pid==0getpid() 獲取進程id*/printf("子進程 PID: %d\n", getpid());} else {// 父進程pid 大于0printf("父進程 PID: %d\n", getpid());}return 0;
}
????????????????The ?child process and the parent process run in separate memory spaces. ?At
the time of fork() both memory spaces have the same content. ?Memory writes,
file ?mappings (mmap(2)), and unmappings (munmap(2)) performed by one of the
processes do not affect the other.
子進程和父進程運行在獨立的內存空間中。調用fork()
時,兩者的內存空間內容完全一致。任一進程對內存的寫入、文件映射(mmap(2)
)或解除映射(munmap(2)
)操作均不會影響另一進程。
#include <unistd.h>
#include <stdio.h>int main() {int val = 10;pid_t pid = fork();if (pid == 0) {val = 20; // 子進程修改不影響父進程printf("Child val: %d\n", val);} else {printf("Parent val: %d\n", val); // 輸出仍為10}return 0;
}
2. 僵尸進程
????????僵尸進程(Zombie Process)是指已經完成執行(通過exit()
系統調用終止)但其退出狀態尚未被父進程讀取(通過wait()
或waitpid()
系統調用)的進程。
? ? ? ? 產生原因:父進程還存在,但是去做的別的事情了(比如在一個死循環,沒有退出),此時子進程退出之后,就變成了僵尸進程。
(可以用ps -ef 查看,進程的狀態欄為defunct,這就是所謂的“僵尸”進程)
3. 孤兒進程
? ? ? ? 孤兒進程指父進程終止或退出后仍在運行的子進程。這類進程會被系統內核的init
進程(PID 為 1)接管,最終由init
負責回收資源。
? ? ? ? 產生原因:父進程比子進程先結束。
4.? wait? waitpid
????????wait, waitpid?- 回收進程
#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *wstatus);pid_t waitpid(pid_t pid, int *wstatus, int options);
? ? ? ? ?int *wstatus? 狀態
????????退出狀態
? ? ????父進程監聽子進程退出狀態,如果正常退出,則輸出OK
? ? ????如果子進程異常,退出則輸出error
? ? ?????exit(-2)返回給父進程子進程退出狀態
? ? ?????wait(&state);
? ? ? ? ?waitpid(-1,&state,WNOHANG );
? ? ?????status == 0 正常退出
? ? ?????status != 0 異常退出
int options
? ? ? ? WNOHANG ? ? return immediately if no child has exited.
? ? ? ?WUNTRACED ? also ?return ?if ?a ?child ?has ?stopped ?(but ?not ?traced ?via
ptrace(2)). ?Status for traced children which ?have ?stopped ?is
provided even if this option is not specified.? ? ? ?WCONTINUED (since Linux 2.6.10)
also ?return ?if a stopped child has been resumed by delivery of
SIGCONT.
WNOHANG
立即返回,若沒有子進程退出。
???????????????當返回值ret>0的時候表示子進程退出
? ? ? ? ? ? ???當返回值ret=0的時候表示等待子進程的退出
WUNTRACED
若子進程停止(但未被ptrace(2)跟蹤),也返回狀態。對于被跟蹤且停止的子進程,即使未指定此選項,仍會提供其狀態信息。
WCONTINUED(自Linux 2.6.10起)
若停止的子進程因收到SIGCONT信號而恢復執行,也返回狀態。
wait 阻塞等待回收進程
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main(int argc, char const *argv[])
{printf("hello wprld\n");pid_t id = fork();if (id == -1){printf("fork fail\n");}else if (id > 0){printf("[%d]我是父進程\n", getpid());wait(NULL); //等待子進程執行完畢后再往下執行,阻塞等待回收,循環掃描子進程printf("子進程已回收 結束\n");}else{int count = 10;while (count--){printf("[%d]我子進程%d\n", getpid(), count);sleep(1);}}return 0;
}
waitpid? 非阻塞等待回收
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main(int argc, char const *argv[])
{printf("hello wprld\n");pid_t id = fork();if (id == -1){printf("fork fail\n");}else if (id > 0){while(1){int ret = waitpid(-1, NULL, WNOHANG);printf("ret=%d\n", ret);if (ret < 0)break;sleep(1);}//等價//while(waitpid(-1,NULL,WNOHANG)==0); }else{int count = 10;while (count--){printf("[%d]我子進程%d\n", getpid(), count);sleep(1);}}return 0;
}