父子進程的關系:
子進程是父進程的副本。子進程獲得父進程數據段,堆,棧,正文段共享。(子分配了一塊新的內存,但是代碼段指向父進程,也就是說不論幾個子進程都只有一個code段)
?? ?
?? ?在fork之后,一般情況那個會先運行,是不確定的。如果非要確定那個要先運行,需要IPC機制。
?? ?
?? ?區別:
?? ?1)fork的返回值
?? ?2)pid不同
進程的終止:8種情況
? ? 1)main 中return
?? ?2)exit(), c庫函數,會執行io庫的清理工作,關閉所有的流,以及所有打開的文件,調用清理函數(atexit)。
?? ?(int atexit(void (* function) (void)))(回調函數,用于調用程序員自己寫的清理函數)?
?? ?3)_exit,_Exit 會關閉所有的已經打開的文件,不執行清理函數。
?? ?4) ?主線程退出
?? ?5)主線程調用pthread_exit(使單個線程退出)
?? ?6)abort()(強行終止線程,作為異常終止)
?? ?7)signal ? kill pid(外部信號,例如kill)
?? ?8)最后一個線程被pthread_cancle(系統的線程取消請求,但其實不等于線程結束)
exit ? ? 庫函數
? ? 退出狀態,終止的進程會通知父進程,自己使如何終止的。如果是正常結束(終止),則由exit傳入的參數。如果是異常終止,則有內核通知異常終止原因的狀態。任何情況下,負進程都能使用wait,waitpid獲得這個狀態,以及資源的回收。
?? ?void exit(int status)?
?? ?exit(1);
?? ?功能:
?? ??? ?讓進程退出,并刷新緩存區
?? ?參數:
?? ??? ?status:進程退出的狀態
?? ?返回值:
?? ??? ?缺省
?? ?
?? ?EXIT_SUCCESS?? ?0
?? ?EXIT_FAILURE? ? 非0(1~128,c語言錯誤列表共有128個)
?? ?return ?當該關鍵字出現在main函數中時候可以結束進程
?? ??? ??? ?如果在其他函數中則表示結束該函數。
?? ?exit -> 刷新緩存區 -> atexit注冊的退出函數 -> _exit
atexit(回調函數)
int atexit(void (*function)(void));
?? ?功能:
?? ??? ?注冊進程退出前執行的函數(也就是參數function,需要程序員自己構建)
?? ?參數:
?? ??? ?function:函數指針
?? ??? ??? ?指向void返回值void參數的函數指針
?? ?返回值:
?? ??? ?成功返回0
?? ??? ?失敗返回非0
?? ?當程序調用exit或者由main函數執行return時,所有用atexit
?? ?注冊的退出函數,將會由注冊時順序倒序被調用
wait:
?? ?pid_t wait(int *status);
功能:該函數可以阻塞等待任意子進程退出
? ? ? 并回收該進程的狀態。
?? ? ?一般用于父進程回收子進程狀態。
參數:status 進程退出時候的狀態
?? ? ?如果不關心其退出狀態一般用NULL表示
?? ? ?如果要回收進程退出狀態,則用WEXITSTATUS回收。
返回值:成功 回收的子進程pid
?? ??? ?失敗 -1;
退出狀態:
WIFEXITED(status) ?是不是正常結束
WEXITSTATUS(status) 使用這個宏去接收返回值(exit函數的返回值)
WIFSIGNALED(status) 是不是收到了信號而終止的
WTERMSIG(status)如果是信號終止的,那么是幾號信號。
(比如使用終端的kill命令,kill -9 pid號,此時的這個宏得到的值應該是9)
以上退出狀態兩個兩個一組使用:
int status;pid_t recycle_pid = wait(&status);if(WIFEXITED(status)){ printf("child normal terminal,recycle pid %d , exit value %d\n",recycle_pid,WEXITSTATUS(status));}if(WIFSIGNALED(status)){printf("child terminal by signal ,rrecycle pid %d, signal num %d \n",recycle_pid,WTERMSIG(status));}
注:
? ? 1)如果所有的子進程都在運行,在阻塞
?? ?2)如果一個子進程終止,正在等待的父進程則獲得終止狀態,獲得子進程的狀態后,立刻返回。
?? ?3)如果沒有子進程,則立即出錯退出。
?
waitpid:
pid_t waitpid(pid_t pid, int *status, int options);(功能更強大的wait)
?? ?< -1 回收指定進程組內的任意子進程
?? ?-1 回收任意子進程,組內外
?? ?0 回收和當前調用waitpid一個組的所有子進程,組內
?? ?> 0 回收指定ID的子進程
?? ? waitpid (-1,a,0) ?== wait(a);(阻塞等待回收組內外任意子進程)
?? ? status 子進程退出時候的狀態,//一般使用非阻塞,因為如果阻塞的話,無法及時接收到數據
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???如果不關注退出狀態用NULL;
?? ? ?options 選項:(是否阻塞)
?? ? ??? ??? ??? ?0 ?表示回收過程會阻塞等待 ?
?? ??? ??? ??? ?WNOHANG 表示非阻塞模式回收資源。
?? ?返回值:成功 返回接收資源的子進程pid
?? ??? ?失敗 ?-1
?? ??? ?0,