進程概念之孤兒與殭屍

      在瞭解了進程是什麼後,接下來我們來了解一下進程的其他相關。

      進程可以使用命令來進行查看

  •   進程的信息可以通過/proc系統文件夾查看;(如要查看PID爲1 的進程信息,需要查看/proc/1這個文件夾)
  • 大多數進程信息同樣也可以用top和ps這些用戶級工具來獲取

     通過系統調用獲取進程標識符的方法:

     進程ID(PID):調用函數getpid();

     父進程ID(PPID):調用函數getppid();

     在學習過進程的創建和銷燬之後,我們應該會聽過孤兒進程與殭屍進程這兩個概念,接下來就來學習一下這兩個進程的概念以及來由。  孤兒進程與殭屍產生的方式均爲kill+進程名(或者進程ID),若殺死的爲父進程,則產生孤兒進程;若殺死的爲子進程,則產生的爲殭屍進程。

     殭屍進程:殭屍進程就是死後無人收屍,所以演變成殭屍,也就是,父進程還活着,但子進程因爲某些原因而被殺死,然鵝父進程沒有得到子進程死亡的任何通知,所以該子進程就稱爲殭屍進程。

  • 殭屍狀態是一個比較特殊的狀態。當進程退出並且父進程(使用wait()系統調用)沒有讀取到子進程退出的返回代碼時就會產生殭屍進程。
  • 殭屍進程會以種植狀態保持在進程表中,並且會一直在等待父進程讀取退出代碼。
  • 所有,只要子進程退出,父進程還在運行,但父進程沒有讀取子進程狀態,子進程進入Z狀態。

      下面我們就來模擬一下殭屍進程的產生。

#include<stdio.h>
#include<stdlib.h>

int main()
{
	pid_t id=fork();
	if(id<0)
	{
		perror("fork");
		return 1;
	}
	else if(id>0)
	{//parent
		printf("parent[%d] is sleeping...\n ",getpid());
		sleep(30);
	}
	else
	{
	    printf("child[%d] is begin Z....\n",getpid());
	    sleep(5);
	    exit(EXIT_SUCCESS);
	}
	return 0;
}

      測試結果:

         先運行縮寫代碼:


         再打開一個終端,創建一個監控命令行腳本進行監控就可以觀察到進程的狀態:


      殭屍進程的危害:

  • 進程的退出狀態必須被維持下去,因爲它要告訴關係它的進程(父進程),交給它的任務完成的怎麼樣了?可是如果父進程一直不讀取,那子進程就一直處於Z狀態。
  • 維持退出狀態本身就是要用數據維護,也屬於進程基本信息,所有保存在task_struct(PCB)中,也就是說,如果Z狀態一直不退出,PCB就要一直進行維護。
  • 但是你也知道,一個父進程會創建許多子進程,如果不回收,就會造成內存資源的浪費。因爲數據結構對象本身就是就要佔用內存資源。

      孤兒進程:我們可以用字面意思來解釋,孤兒的意思就是無父無母,而我們都知道,進程只有父進程,所有孤兒進程的意思就是父進程已被銷燬,然鵝子進程依然存活,因此,我們把該子進程稱爲孤兒進程。但,如父進程死後,所有的孤兒進程將由1號進程(也就是操作系統所提供的1號進程來管理),當然,前提是子進程不爲殭屍進程。

  • 父進程如果提前退出,那麼子進程後退出,進入Z狀態後,該如何處理呢?
  • 父進程先退出,那麼子進程就稱爲“孤兒進程”。
  • 孤兒進程被1號init進程收養,當然也要有init進程進行回收嘍。

    接下來進行孤兒進程的實現:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
	pid_t id=fork();
	if(id<0)
	{
		perror("fork");
		return 1;
	}
	else if(id==0)
	{//child
		printf("I'm child,pid:%d\n",getpid());
		sleep(10);
	}
	else
	{//parent
		printf("I'm parent,pid:%d\n",getpid());
		sleep(3);
		exit(0);
	}
	return 0;
}

     在監視命令行腳本的監視下,運行結果如下:


  以上就是我對孤兒進程與殭屍進程的簡單總結。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章