子進程退出后,資源沒有釋放,處于僵死狀態。
產生原因: 子進程優先于父進程退出,父進程正在執行其他操作,沒有關注子進程退出,這時候操作系統為了保護子進程退出的原因,不會釋放子進程中的資源,子進程既沒有運行,也沒有退出,處于僵死狀態,成為僵尸進程。
通常情況下解決僵尸進程的辦法就是:
waitpid(pid_t pid,int * status,int options);
pid:子進程的操作句柄
status:保存子進程退出原因。
僵尸程序,options:存儲waitpid函數的等待方式。
返回值:成功返回子進程的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");}}
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态