Linux/Unix分配進程ID的方法以及源代碼實現


       在Linux/Unix系統中。每一個進程都有一個非負整型表示的唯一進程ID。盡管是唯一的。可是進程的ID能夠重用。當一個進程終止后,其進程ID就能夠再次使用了。

大多數Linux/Unix系統採用延遲重用的算法,使得賦予新建進程ID不同於近期終止進程所使用的ID,這主要是為了防止將新進程誤覺得是使用同一ID的某個已終止的先前進程。本文討論了Linux/Unix分配進程ID的方法以及源代碼實現。

分配進程ID的方法

      在大多數Linux/Unix系統中,生成一個進程ID方法是:從0開始依次連續分配,一直到能夠分配的最大的進程ID(不同的系統。這個最大值是不一樣的,比方有些Linux系統是65536)。一旦到達最大值,又一次從某個值(不同的系統,這個值也是不一樣的,比方在Mac OS X和HP-UX系統中,這個值是100)開始依次連續查找那些還沒有被使用的ID。這里分配進程ID的方法,存在潛在的安全問題。由於能夠從系統獲取信息或者提取進程間通信的內容。

考慮到安全問題。部分系統可能用其它方法來分配進程ID,比方隨機分配一個進程ID。

不管用什么方法分配進程ID。系統都須要保證每一個進程ID是獨一無二的。

Linux系統上分配進程ID的源代碼實現

      在Linux系統中,內核分配PID的范圍是(RESERVED_PIDS, PID_MAX_DEFAULT)。在每一個namespace中。PID是依次連續分配的(在不同的namespace的task能夠有同樣的ID)。

一旦ID達到分配到達上限(在pseudo-file /proc/sys/kernel/pid_max中能夠查看能夠分配的最大進程ID),從頭開始查找分配PID。下面是相關的源碼:

struct pid *alloc_pid(struct pid_namespace *ns)
{
	/*省略了一些代碼*/
	for (i = ns->level; i >= 0; i--) {
	    nr = alloc_pidmap(tmp);
	    if (nr < 0)
		goto out_free;
	    pid->numbers[i].nr = nr;
	    pid->numbers[i].ns = tmp;
	    tmp = tmp->parent;
	}
	/*省略了一些代碼*/
}
static int alloc_pidmap(struct pid_namespace *pid_ns)
{
        int i, offset, max_scan, pid, last = pid_ns->last_pid;
        struct pidmap *map;

        pid = last + 1;
        if (pid >= pid_max)
                pid = RESERVED_PIDS;
        /* and later on... */
        pid_ns->last_pid = pid;
        return pid;
}

       注意在Linux內核中,進程PID實現並不不過一個int標識符號(當然返回給應用程序,PID不過int類型的數值)。相關實現的結構體在/include/linux/pid.h中能夠找到。除了ID外。它還包含跟這個ID相關的task列表、引用計數器和一個能夠方便查找的hashed list。

進程ID分配須要注意的事項
       1、僵屍進程的PID是臨時不能用的。須要其父進程收集器全部的終止狀態才干使用,也就是說須要調用類似wait()函數后,才干使用。
       2、詳細實現時,系統能夠隨機分配進程PID(當然是保證沒有被其它進程使用),因此在應用程序中,不要依賴於進程PID的分配方式。
       3、在用戶空間(user space)可能看到分配的進程ID並不連續,這是由於在應用程序兩個fork之間,內核調度程序(scheduling)可能創建了一個進程。

其實。這樣的情況是常常發生的。

參考資料

《UNIX環境高級編程》(第二版)
http://superuser.com/questions/135007/how-are-pids-generated
http://stackoverflow.com/questions/3446727/how-does-linux-determine-the-next-pid
http://en.wikipedia.org/wiki/Process_identifier



免責聲明!

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



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