我在閱讀有關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導致應用程序在退出時不會退出?