2010-06-22 180 views
44

我正在編寫Linux守護進程。我找到了兩種方法來做到這一點。Linux守護進程

  1. 通過致電fork()並設置sid守護進程的進程。
  2. &運行程序。

哪種方法可以做到這一點?

+1

你可以使用nohup:http://stackoverflow.com/questions/958249/whats-the-difference-between-nohup-and-a-daemon – rogerdpack 2013-06-24 20:39:39

回答

76

http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16

下面是成爲守護程序以下步驟:

  1. 叉(),所以家長可以退出,這將控制返回到命令行或殼調用程序。這一步是必需的,以確保新流程不會成爲流程組的領導者。如果你是一個流程組組長,下一步,setsid()失敗。
  2. setsid()成爲進程組和會話組的領導者。由於控制終端與會話相關聯,並且此新會話尚未獲得控制終端,所以我們的過程現在沒有控制終端,這對於守護進程來說是好事。
  3. 再次fork()以便父母(會話組領導)可以退出。這意味着我們作爲非會議組織的領導者永遠不能重新獲得控制終端。
  4. chdir(「/」)確保我們的進程不會保留任何目錄正在使用。如果不這樣做,可能會導致管理員無法卸載文件系統,因爲它是我們當前的目錄。 [相當於,我們可以更改爲任何包含守護進程操作重要文件的目錄。]
  5. umask(0)以便我們可以完全控制我們編寫的任何內容的權限。我們不知道我們可能繼承了什麼樣的umask。 [這一步是可選的]
  6. close()fds 0,1和2.這將釋放我們從父進程繼承的標準輸入,輸出和錯誤。我們無法知道這些fds可能被重定向到哪裏。請注意,許多守護進程使用sysconf()來確定_SC_OPEN_MAX的限制。 _SC_OPEN_MAX告訴你最大的打開文件/進程。然後在一個循環中,守護進程可以關閉所有可能的文件描述符。你必須決定是否需要這樣做。如果您認爲有可能打開文件描述符,則應關閉它們,因爲併發文件描述符的數量有限制。
  7. 爲stdin,stdout和stderr建立新的開放描述符。即使你不打算使用它們,打開它仍然是一個好主意。精確處理這些是一個品味問題;例如,如果您有日誌文件,則可能希望將其作爲標準輸出或標準錯誤打開,然後以標準輸入打開「/ dev/null」;或者,你可以打開'/ dev/console'作爲stderr和/或標準輸出,'/ dev/null'作爲標準輸入,或者任何其他適合你的特定守護進程的組合。

更重要的是,只需調用daemon()功能,如果它是可用的。

+1

你必須關閉所有打開的描述符。否則,這些文件可能會繼續有一個引用,例如,這會阻止它們被刪除。這很像chdir(「/」)。 – 2010-08-24 09:05:00

+2

@ n-alexanderso - 是守護進程()雙叉? – Dannyboy 2014-06-20 16:35:00

+1

在Ruby的WEBrick守護進程(切換源)一個很好的例子:http://ruby-doc.org/stdlib-2.1.1/libdoc/webrick/rdoc/WEBrick/Daemon.html – 2014-10-10 13:48:36

2

其實做一個守護進程你必須雙叉。

使用&運行該程序會使shell在後臺運行程序,但不會使其成爲守護進程。守護進程將init(pid 1)作爲父項,這就是爲什麼需要雙叉。如果你的程序是一個守護進程,那麼最好的方式是自己處理這個問題(還有更多的方法,參見here)。你也可以使用start-stop-daemon程序。

5

第一個。第二個不是守護進程,而是在後臺運行。守護程序應該在它自己的會話和進程組上,並且應該是而不是有一個控制終端。

+1

但我仍然不明白什麼是使用設置自己的會話和進程組 – Poorna 2010-06-22 17:45:52

2

你在用什麼語言?一些語言具有助手方法,可以使守護進程更簡單。例如,Ruby有daemons包。

+0

我們使用C++ – Poorna 2010-06-22 17:44:17

11

只需使用daemon(3)(從unistd.h)。

的守護程序()函數是用於希望從 控制終端中跳出來並在 背景系統守護進程運行的程序 。 ...

+0

我花了好幾天調查我怎麼能作爲使用詹金斯直到我看到你的建議Ubuntu的後臺進程運行燒瓶應用。謝謝! 用shell命令解決我的問題 'export BUILD_ID = dontKillMe' 'daemon flask run' – barbarian 2017-10-25 22:55:08

28

我建議不要寫你的程序作爲一個守護進程在所有。使它在文件描述符,當前目錄,進程組等給定的前臺運行。使用start-stop-daemon(8),init(8),runsv(來自runit),upstart,systemd或其他來啓動你的進程作爲一個守護進程。也就是說,讓用戶決定如何運行你的程序,而不是強制它必須作爲守護進程運行。

+6

+1。至少,提供在前臺運行的選項。 – 2012-05-22 16:12:44

+0

很抱歉帶來一箇舊的答案,但monit是否也可以啓動您的進程作爲守護進程? – allaire 2013-07-15 02:08:20