僵尸程序,Linux---僵尸進程的解決辦法

 2023-10-15 阅读 21 评论 0

摘要:僵尸進程 子進程退出后,資源沒有釋放,處于僵死狀態。 產生原因: 子進程優先于父進程退出,父進程正在執行其他操作,沒有關注子進程退出,這時候操作系統為了保護子進程退出的原因,不會釋放子進程中的資源,子進程既沒有

僵尸進程

子進程退出后,資源沒有釋放,處于僵死狀態。

產生原因: 子進程優先于父進程退出,父進程正在執行其他操作,沒有關注子進程退出,這時候操作系統為了保護子進程退出的原因,不會釋放子進程中的資源,子進程既沒有運行,也沒有退出,處于僵死狀態,成為僵尸進程。

通常情況下解決僵尸進程的辦法就是:
waitpid(pid_t pid,int * status,int options);
pid:子進程的操作句柄

  • pid<-1 等待進程組識別碼為 pid 絕對值的任何子進程。
  • pid=-1 等待任何子進程,相當于 wait()。
  • pid=0 等待進程組識別碼與目前進程相同的任何子進程。
  • pid>0 等待任何子進程識別碼為 pid 的子進程。

status:保存子進程退出原因。

  • 如果不需要進程退出原因,則設置為NULL

僵尸程序,options:存儲waitpid函數的等待方式。

  • 為0默認阻塞等待。
  • WNOHANG 若pid指定的子進程沒有結束,則waitpid()函數返回0,不予以等待。若結束,則返回該子進程的ID。
  • WUNTRACED 若子進程進入暫停狀態,則馬上返回,但子進程的結束狀態不予以理會。WIFSTOPPED(status)宏確定返回值是否對應與一個暫停子進程。
    子進程的結束狀態返回后存于 status,底下有幾個宏可判別結束情況:
  • WIFEXITED(status)如果若為正常結束子進程返回的狀態,則為真;對于這種情況可執行WEXITSTATUS(status),取子進程傳給exit或_eixt的低8位。
  • WEXITSTATUS(status)取得子進程 exit()返回的結束代碼,一般會先用
    WIFEXITED 來判斷是否正常結束才能使用此宏。
  • WIFSIGNALED(status)若為異常結束子進程返回的狀態,則為真;對于這種情況可執行WTERMSIG(status),取使子進程結束的信號編號。

返回值:成功返回子進程的pid,失敗返回0。

//使用waitpid等待子進程退出
int main()
{ signal(SIGCHLD,sigcb);pid_t pid = fork();if(pid == 0){sleep(5);//子進程睡眠5秒鐘后退出exit(0);}wait(-1,NULL,0);while(1){printf("this is parents\n");}return 0;
}

如果waitpid為阻塞等待,則父進程一直在等子進程退出,直到子進程退出后才執行自己的操作,有沒有一種父進程在執行自己的操作,當子進程退出信號發出時,父進程再來釋放子進程。

如果這樣我們需要先知道子進程退出時,操作系統給父進程發送什么樣的信號,來通知父進程。
17號信號:SIGCHLD
在這里插入圖片描述
但是這個SIGCHLD為進程默認忽略處理信號,這下我們知道為什么父進程不會注意子進程退出。
現在我們知道子進程退出時,操作系統會給父進程發送17號信號,但是我們如何自定義處理該信號呢?
signal自定義信號處理函數。

//我們通過信號處理函數來通知父進程
void sigcb(int signo)
{wait(-1,NULL,0);
}int main()
{ signal(SIGCHLD,sigcb);pid_t pid = fork();if(pid == 0){sleep(5);//子進程睡眠5秒鐘后退出exit(0);}while(1){printf("this is parents\n");}}

但是這樣做會產生一個問題:如果父進程有多個子進程呢,由于SIGCHLD信號為非可靠信號,在信號的集合中只保存一份,所以在調用signal函數時,會出現想要釋放多個子進程,但事實上只釋放一個,導致子進程沒有完全處理,同樣會產生僵尸進程。

centos shutdown。解決辦法:循環調用waitpid函數,防止出現進程沒有完全處理的情況。

void sigcb(int signo)
{while(wait(-1,NULL,0)>0);//如果有子進程退出,則循環處理       	
}int main()
{ signal(SIGCHLD,sigcb);pid_t pid = fork();if(pid == 0){sleep(5);//子進程睡眠5秒鐘后退出exit(0);}while(1){printf("this is parents\n");}}

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/140466.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息