如何讓程式真正地在後台執行?

2021-10-04 16:18:00 字數 1982 閱讀 1952

如何實現乙個守護程序?如何讓程式在後台執行?這是後台開發面試常問的一道題,那麼守護程序到底是什麼?又該如何實現?

守護程序通常生存期長,很多是在系統啟動時啟動,系統退出時才關閉。它們的特點通常沒有控制終端,後台執行。

有人可能會會心一笑,後台執行程式,我知道呀。還有兩種方式呢

$ ./hello &

看,多麼簡單。但是執行之後,你試著關閉當前終端,你會發現程式會停止執行,因為一旦關閉終端,程式會收到乙個訊號sighup,而收到該訊號預設的動作就是程式退出。

沒關係啊,我還有招:

$ nohup ./hello & #注意這裡&是必要的,否則不會變成後台程序

$ jobs

[1]+  running                 nohup ./hello &

我使用nohup命令總可以了吧?

挺好的,nohup會忽略sighup命令,並有了&的加持,即便終端關了,也能繼續執行。但它的終端輸出還會記錄預設還在nohup.out檔案中,同時,如果將huponexit關閉,它同樣難逃命運:

$ shopt -s huponexit  #shopt -u huponexit 設定為off

$ shopt |grep onexit

huponexit       on

一旦終端退出(ctrl+d)後,nohup也救不了。

下面要介紹的守護程序一一種完全脫離終端,有著自己的會話。

如果你在你的linux系統中執行下面的命令:

$ ps -elf

就會發現一些程序的tty列是?,當然這並不是說明它們是守護程序,而那些用括起來的,是核心守護程序

想象一下,如果沒有任何人登入的伺服器上面的執行程式,難道每次執行的時候都要使用nuhup+&?況且,一旦系統的huponexit選項是開啟的,這種方式仍然無法避免終端關閉程式就退出的命運!

那麼就需要實現使用者守護程序了,或者說daemon化。

其實現過程基本遵循以下原則:

實際上,從上面的描述可以發現,這些規則都有幾乎相同的目標,那就是不想成為富二代,擺脫父親的控制。(在fork的介紹中,我們說到,兒子從父親那裡繼承了很多東西)

所以通過這些也可以明白,有些規則並不是完全強制的,可根據實際程式的情況進行設定,不過按照常規做法是乙個比較好的選擇。

編譯執行,你就會發現,它已經可以歡脫地執行啦。

**中有幾個點,需要關注一下。為了保留printf的輸出,我在daemonize函式中,並沒有關閉所有的檔案描述符,0,1,2可以參考《如何理解 linux shell中「2>&1」?》,當然了,如果想讓printf的輸出儲存到檔案,也有方法,可以參考《如何優雅地將printf的列印儲存在檔案中?》,這裡就不再贅述了。

實際上,已經有乙個介面可以幫我們做這些事情:

#include 

int daemon(int nochdir, int noclose);

即daemon函式,它有兩個引數

簡單例子:

如果你還要實現單例化,使得同時只有乙個該程序執行。

以上就程序後台執行以及是守護程序實現的介紹,關鍵點有

附上daemon的原始碼:

int daemon(nochdir, noclose)

int nochdir, noclose;

if (setsid() == -1)

return (-1);

if (!nochdir)

(void)chdir("/");

if (!noclose && (fd = open(_path_devnull, o_rdwr, 0)) != -1) 

return (0);

}

讓程式在後台執行 nohup使用

在linux操作時,我們想讓某個程式在後台執行,例如訓練模型。我們可以通過使用nohup命令,並將輸出記錄在文件中。例如,我建立了乙個 run.sh 的指令碼 vi run.sh 在指令碼中寫入你想執行的程式指令碼,esc,然後ctrl 輸入 wq 儲存退出 python train.py 有時候需...

如何讓你的linux程式在後台靜默執行

最近寫了個工具,需要在後台靜默執行,即使關閉了當前linux命令列視窗,也不會有影響,我們來戲說 1.寫main.cpp,生成可執行的二進位制檔案main 要注意許可權,確保可執行 2.寫指令碼run.sh 要注意許可權,確保可執行 bin bashallfile ls test for onefi...

如何讓你的linux程式在後台靜默執行

最近寫了個工具,需要在後台靜默執行,即使關閉了當前linux命令列視窗,也不會有影響,我們來戲說 1.寫main.cpp,生成可執行的二進位制檔案main 要注意許可權,確保可執行 2.寫指令碼run.sh 要注意許可權,確保可執行 bin bashallfile ls test for onefi...