守護程序建立 setsid

2021-08-09 13:54:18 字數 1889 閱讀 4304

論壇上看到的,留著  一、

int main()

二、int main()

{if(fork())

exit(0);

setsid()

//守護程序**

其實兩種方法在某種程度上來說都可以,但是double fork會帶來一些區別。

首先,我們得搞清楚這些**都幹了什麼:

1、第一次fork,確保當前的process一定不是session leader,關於session,繼續往下看

2、setsid,建立新的session,因為session leader呼叫setsid不會建立新session,所以我們才需要之前的那個fork。

那session到底是什麼?當你通過控制台登入時,你就建立了乙個session,乙個session就是乙個controlling terminal、乙個controlling process group,再加上一堆後台process group,其中controlling process一般就是login shell,controlling terminal就是你在敲鍵盤看顯示器的那個「終端」。在shell中,你可以用"&"將乙個命令在後台執行,或者你可以按ctrl-z,然後用bg命令將其放入後台,這時你可以用jobs命令看到後台執行的程序,這些後台程序就是background process group

看看當你logout的時候會發生什麼,此時controlling terminal會被關閉,這個session中所有程序都會收到sighup和sigterm/sigquit,對於這些訊號的預設操作就是結束程序。

作為乙個daemon,你當然不希望使用者logout的時候就退出,解決方案有幾種,一種就是忽略上述所有訊號,例如nohup程式幹的就是這個,但這樣做有個小問題,很多程式使用訊號作為一種簡單的ipc機制,忽略這些訊號會導致這種ipc失效;另外一種方案就是讓程序從這個controlling terminal上脫離,setsid將會建立乙個新的session,使當前程序成為新session的leader,並且不再關聯之前session的controlling terminal。

3、第二次fork,這件事情有點晦澀,其實很多文件上並沒說的太清楚,具體原因是這樣的,即使乙個程序建立了新的session,它依然有可能獲得乙個controlling terminal,比如你可以用ioctl(tiocsctty),這樣做的後果就是,新的session有了controlling terminal,然後前面我們提到的所有問題依然可能發生。為了徹底解決這個問題,我們需要第二次fork,因為ioctl(tiocsctty)手冊中在非常不起眼的地方提到了,只有session leader才能為session開啟controlling terminal,第二次fork之後,子程序就是session中第二個程序,它這輩子再沒機會成為session leader了(除非它呼叫setsid),也就再沒能力開啟controlling terminal了。這樣我們就一勞永逸的解決了所有問題。

所以,如果你的程式行為很固定,你知道它不會無聊到去開啟controlling terminal的話,第二次fork其實是不必要的,但是如果你是在寫乙個庫,而且不知道使用它的程式到底會有什麼樣的行為,你最好還是再fork一次。

其實幹了所有上述的事,依然還有一些遺留問題,你還需要:

1、chdir("/"),這樣可以防止你的程式工作目錄所在的檔案系統無法umount的問題

2、close/reopen所有你不需要的fd,尤其是stdin/stdout,因為這些fd是從父程序繼承下來的,如果它們是管道,而對端有關閉了,讀寫它們會產生sigpipe

3、設定正確的umask,這也是從父程序繼承下來的,不一定是你想要的值

4、設定適當的env,同上

5、設定適當的sigmask

6、如果你的daemon需要建立子程序,你可能還需要signal(sigchld, sig_ign),防止退出的子程序成為zombie

linux 守護程序詳解及建立守護程序

linux 守護程序詳解及建立守護程序 守護程序是一種後台執行並且獨立於所有終端控制之外的程序。守護程序的啟動 要啟動乙個守護程序,可以採取一下幾種方式 守護程序的建立 先來看乙個守護程序建立的例子 include include include include define maxfd 64 vo...

Linux 守護程序建立

守護程序是在後台執行,不受使用者的控制 守護程序沒有任何存在的父程序。如果乙個程序想成為守護程序,有fork 建立 然後終止父程序,脫離資源。例子 void init daemon int pid,i pid fork if pid exit 0 結束父程序 else exit 1 失敗退出 是子程...

subprocess建立守護程序

剛開始我在做爬蟲,爬蟲程式用python程式呼叫,但有時候爬蟲程式會死掉,掛了,所以程式會一直停留在那兒,該怎麼辦呢?我想可以建立乙個堅守程式,讓os.system 呼叫爬蟲程式能在一定時間內未執行完時,強制殺死,並重新開始,但根據結構化程式,順序執行沒辦法做到這一點,我知道肯定需要執行緒機制實現,...