Linux進程wait函數、僵屍進程、孤兒進程


 

1.僵屍進程、孤兒進程


  僵屍進程:當一個子進程結束運行(一般是調用exit、運行時發生致命錯誤或收到終止信號所導致)時,子進程的退出狀態(返回值)會報給操作系統,系統則以SIGCHLD信號告知父進程,此時子進程的進程控制塊(PCB)仍駐留在內存中。父進程收到SIGCHLD后,會調用wait()函數獲取子進程的退出狀態,然后內核就可以從內存中釋放已結束的子進程的PCB;而如若父進程沒有這么做的話,子進程的PCB就會一直駐留在內存中,即成為僵屍進程。

  孤兒進程:當父進程退出,而它的一個或多個子進程還在運行,那么那些子進程將成為孤兒進程。孤兒進程將被init進程(進程號為1)所收養,並由init進程對它們完成狀態收集工作,因此孤兒進程並沒有什么危害,系統中會經常有這種情況。

2.wait、waitpid函數的使用方法


  wait、waitpid函數由父進程調用來讀取子進程的返回信息,使子進程完全終止。

  【1】pid_t wait(int *status);    

    wait函數會在父進程中阻塞,等待子進程結束,如果子進程結束,則返回子進程的PID。如果沒有子進程則立刻返回-1。

  【2】pid_t waitpid(pid_t pid, int *status, int options);    

    waitpid函數等待子進程結束(options設置為WNOHANG時為非阻塞),如果子進程結束,則返回子進程的PID。如果沒有子進程則立刻返回-1,如果是非阻塞的並且子進程還沒有結束,則返回0。

    由於這兩個函數會阻塞等待(非阻塞時也需要輪詢執行),所以常規使用方式為:當子進程退出時會給父進程發送SIGCHID信號,因此父進程捕獲SIGCHID信號,並在信號處理函數中調用waitpid函數來結束一個子進程。如下:

void sig_chld(int signo) { 
	pid_t   pid; 
	int     stat; 
	
	while((pid = waitpid(-1, &stat, WNOHANG)) > 0){ 
		printf("child %d terminated\n", pid); 
	} 
	
	return; 
}

signal(SIGCHLD, sig_chld);

3.問題


  問題1:如果有多個子進程,則任意一個子進程結束時,wait函數就會返回,所以此時可以循環判斷wait返回-1時(另外返回-1時,errno 等於EINTR時表示中斷,所以此時需要繼續循環等待),才表示所有子進程都退出了。

    

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM