在 Linux 上雙擊應用程式時誰會分叉?

在 Linux 上雙擊應用程式時誰會分叉?

所以我知道什麼時候在 shell 中運行一個可執行文件,然後 shell 將其分叉到一個子進程中,然後執行 exec 來獲取可執行檔的程式和資料記憶體。因此,如果我的 shell 現在關閉/退出,那麼它的所有關聯子進程也會被終止。

我讀到在linux中每個行程都是透過fork() exec()建立的。我很好奇,並且想知道每當透過雙擊其圖標啟動應用程式時,哪個進程 forks() exec() 它,我知道它是某個作業系統進程,我想知道哪個進程

謝謝你!

回答 追蹤到 /sbin/upstart

答案1

首先,有一點術語

可執行檔是系統中一個簡單的檔案。簡而言之,進程是執行嵌入在可執行檔中的程式的外殼。


你是對的啟動可執行檔的方式:

  1. 父進程(已經存在)forks 本身,從該點開始引入兩個執行流。一個生活在父進程中,一個生活在一個全新的進程。
  2. 新(子)程序將自身靜音以執行要執行的可執行檔的程式。這是使用一個系統調用exec家庭。

以雙擊可執行圖示的圖形介面為例,您可以從顯示您單擊的圖示的進程中分叉可執行文件,基本上使用以下原始程式碼:

const char *exe_path = taken_from_icon();
int pid = fork();
if(pid == 0)
{
    // I am the new child
    execl(exe_path, exe_path, NULL);
    // exec only return in case of failure
    exit(EXIT_FAILURE);
}
// I am the graphical interface,
// Continue and wait for another clic

但是死亡與親子關係孩子的情況並不完全像你說的。

基本上,當父進程仍然處於活動狀態時,子進程是其父親的子進程(是的!-)它的 PPID(父進程 ID)設定為派生它的仍然活動的進程。

當父進程終止時,情況就會改變。子進程繼續存活,但其 PPID 被設定為仍然存活的祖父進程。總有一個,因為init進程永遠不會消亡。


事實上,當 shell 本身死亡時,shell 子代也會死亡,這是一個特定的事實。我認為有兩個原因:

  • 第一個:shell 通常維護它派生的 PID 清單。當貝殼死亡時,它會殺死所有的人。主要 shell 有一個disown內建指令,可以從該清單中刪除子進程,並在 shell 終止時讓它繼續存在。看bash 手冊頁:

    預設情況下,shell 在收到 SIGHUP 後退出。在退出之前,互動式 shell 會重新傳送給所有正在執行或已停止的作業 SIGHUP。停止的作業將會被傳送 SIGCONT 以確保它們收到 SIGHUP。為了防止 shell 向特定作業發送訊號,應該使用 disown 內建指令將其從作業表中刪除(請參閱下方的 SHELL BUILTIN 指令),或使用 disown -h 將其標記為不接收 SIGHUP。

  • 第二個:shell 子級通常將其 stdin、stdout 和 stderr 透過管道連接到 shell 本身。如果 shell 停止使用子 stdout(通常是列印它),或關閉其管道端,則子進程在寫入其 stdout 時可能會失敗,這可能會阻止或殺死它。

相關內容