2013-03-05 68 views
1

我在閱讀有關Linux進程組和會話的信息。從this site我看到:當我註銷時,爲什麼我的守護程序不會終止?

當用戶登錄了系統,內核需要終止用戶已運行的所有進程...要簡化這一任務,過程組織成組會議。會話的ID與通過setsid()系統調用創建會話的進程的PID相同。該過程被稱爲該會話組的會話負責人。那個過程的所有後代都是那屆會議的成員,除非他們特別從中脫離出來。 setsid()函數不接受任何參數並返回新的會話ID。

本文沒有說的是操作系統決定終止用戶的會話。我最初的假設是,當有人登錄TTY時,TTY是會話負責人,並且該會話中調用的所有進程都屬於它,除非他們調用setsid()。然而,如最簡單的例子所證實的,這顯然是錯誤的。考慮這個「守護進程」 ......(我知道這是不是一個真正的守護進程,但它確實叉)...

#include 
#include 
#include 
#include 

int main(void) { 

    pid_t pid = fork(); 

    if(pid < 0) { 
    perror("fork"); 
    exit(EXIT_FAILURE); 
    } 

    if(pid == 0) { 
    FILE * heartbeat_file = fopen("daemon.out", "w"); 
    int hb = 0; 
    while(1) { 
     fprintf(heartbeat_file, "%d\n", hb); 
     fflush(heartbeat_file); 
     hb++; 
     sleep(1); 
    } 
    } 
    exit(EXIT_SUCCESS); 
} 

從代碼中,我們看到孩子不斷地寫到一個文件,而父退出。請注意,我從不打電話給setsid()

如果我登錄,運行守護進程,然後註銷,然後登錄,守護進程仍在運行!我可以刪除對fork()的呼叫,並且按照預期,該進程在我註銷時終止。任何人都可以解釋爲什麼fork導致應用程序在退出時不會退出?

回答

1

當您讓父項退出時分叉時,將創建一個孤立進程(http://en.wikipedia.org/wiki/Orphan_process)。 此類孤兒重新註冊到init過程。我會從你所觀察到的情況出發,重新修改會話的ID。

測試這個假設的直接方法是讓父母等待孩子(對不起,我現在不在我的Linux機器上,並且不能這樣做)。

相關問題