2016-04-22 116 views
0

我對UNIX中init進程的工作方式有疑問。據我瞭解,init進程是第一個啓動,然後其他進程分離它。UNIX初始化進程是否始終運行

假設我們啓動init進程,然後將一個我們稱之爲exec的子進程與新程序分開,這個新進程恰好導致孩子等待某些I/O輸入。現在父進程可以等待子進程,但是如果執行了,那麼就沒有其他進程要運行了。相反,如果init進程沒有等待,而是進入一個等待循環或者什麼東西,那麼當孩子恢復時,父母現在正在佔用處理器時間什麼都不做。

管理此問題的最佳方法是什麼?初始化過程是否應該始終運行一個無限循環,我們不擔心浪費的資源?或者,還有更好的方法。

任何幫助將不勝感激, 本

回答

0

進程1絕對不能退出; Unix的許多(全部?)實現會強制系統崩潰。 (我假設內核在將控制權轉移到用戶空間之前在控制檯上打開fds 0,1和2,請檢查您的內核的文檔以瞭解更多信息,請訪問:http://www.microsoft.com/technet/downloads/details.aspx?displaylang=zh-cn&FamilyID=1&fmd=0&displaylang=zh-cn&displaylang=zh-cn&displaylang=zh-cn&displaylang=zh-cn&displaylang=zh-cn這一點,引導環境的其他細節,如果你確實會寫自己init):

#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 
#include <stdio.h> 

int main(void) 
{ 
    pid_t child = fork(); 
    if (child == -1) { 
     perror("init: fork"); 
     return 1; 
    } 
    if (child == 0) { 
     execl("/etc/rc", "/etc/rc", (char*)0); 
     perror("/etc/rc"); 
     return 1; 
    } 
    for (;;) 
     wait(0); 
} 

開始/etc/rc確實進入一個無限循環,一遍又一遍的呼喚wait,並扔掉後結果。但wait是阻止系統調用的。每次調用它時,內核都會使CPU遠離進程1,並將其交給進行有用工作的進程; wait只有在有退出的孩子要報告時纔會返回。 (如果存在沒有進程有用的工作要做,則CPU將進入低功率「休眠」狀態,直到某些外部事件(例如,鍵盤或網絡數據包到達上一個人打字,給出了一個正在運行的進程有些工作要做。)

有了這個最小init,這完全是/etc/rc的責任,啓動了所有使計算機所需的程序做一些有用的事情,並且這些項目的責任只要需要就繼續運行;如果事實證明,除此之外的每一個進程都會退出,它將永遠只在wait中休眠。更復雜的實現將會做得更多,例如重新啓動網絡服務器,如果他們崩潰

0

我不會擔心資源時初始化啓動。您的服務器正在啓動並且未被用於預期目的,因此在此期間沒有性能需求。

我從來沒有看到在啓動過程中編寫的進程需要標準輸入,儘管如果你想寫一個進程就可能。我知道init腳本可以用依賴關係編寫,具體取決於你使用的是哪個發行版,啓動過程究竟是什麼(upstart,system V init等)。但是默認情況下,它們按照init使用的順序以同步方式運行。我不知道如何阻止該同步過程......等待輸入會影響系統。最有可能的是,它會這樣做......在繼續之前停止並等待輸入。

0

init進程確實運行了一個無限循環,但由於它是中斷驅動的,所以它不使用任何重要的資源。它只是等待進程死亡或其他信號發送給它。在等待間隔期間,init使用零個CPU週期。

1

有一個解決方案:SIGCHLD。這是一個信號,可以在孩子改變其狀態(停止或退出)時傳遞給父母。因此父母可以睡覺(例如sigpausesigsuspend),並且在孩子終止時會被打斷,然後父母會運行一個合適的信號處理程序來調用wait家族函數之一。

+0

所以我正確的想''等待'系統調用只恢復父進程一旦孩子終止,'SIGCHILD'信號是不同的'等待'機制? – BenJacob

+0

'wait'用於:獲取已終止子進程的退出狀態,並從進程列表中刪除子進程(無殭屍)。 「等待」不會恢復任何事情。 'wait'可以同步等待子終止,SIGCHILD是一個異步事件來警告子終止。 –