2012-09-07 98 views
6

語境如何確保正在運行的進程正在運行?

我有一個Linux [1]管理的一系列第三方守護進程與互動僅限於外殼的系統[2] init腳本,即只有{啓動|重新啓動|停止|狀態}可用。

問題

進程可以假定一個先前運行的進程的PID,的進程的狀態是通過檢查運行的進程與它的PID的存在進行檢查。

方法A運行與PID 123,隨後模具,處理B初始化與PID 123和狀態命令與不可信(錯誤)響應 「OK」。換句話說,我們只檢查PID中是否存在進程來驗證進程是否正在運行,我們假設如果存在具有此PID的進程,則這是所討論的進程。

提出的解決方案

  1. 訊問過程中,使用PID,以確保運行作爲PID是如預期命令/守護進程。這個解決方案的問題是命令和PID都需要匹配;因此需要保持多位信息並保持同步,並且增加了錯誤/邊緣條件的複雜性。
  2. 將PID文件的創建時間與進程的開始時間相關聯,如果進程在PID文件創建時間的某個增量範圍內,我們可以確定命令/守護進程運行如期。

除了使用該PID運行的進程以外,是否有一種標準方法來批准進程/ PID文件的真實性?即我(作爲系統)想知道你(過程)是否在運行,如果你是我認爲你是誰(A而不是B)。

假設我們已經選擇實施上面提出的第二種解決方案,PID創建時間和過程開始時間之間的置信區間/增量是合理的嗎?在這裏,合理的方法可以接受類型1 /類型2錯誤之間的妥協。

[1]的CentOS/RHEL [2]擊

+1

不應該在[ServerFault](http://serverfault.com/)上? – Graham

+0

您可以對第三方守護進程本身進行任何更改嗎?如果是這樣,您可以使用'flock'爲守護進程創建一些文件系統鎖。 –

+2

你確定過程ID一次被重用嗎?我知道Windows就是這種情況,但我沒有在Linux或UNIX上觀察到這種情況。請參閱http://stackoverflow.com/questions/3446727/how-does-linux-determine-the-next-pid – cdarke

回答

5

該文件的內容:

的/ proc/{PID}/CMDLINE

使用命令行開始這個過程。那是你需要的嗎?

+0

在提議的解決方案1中考慮了這一點:它在批准過程時仍需要保留pid和命令的副本。保持這兩點信息雖然合理,但增加了額外的複雜性。 – Gary

+0

加里,你想要「相當肯定」或「確定」的結果嗎?如果估計和近似結果足夠好(只有你可以作爲判斷),然後嘗試實現你的第二個解決方案,如果你的代碼有問題,將它們發佈到StackOverflow。這是一個編程問答網站,而不是系統管理最佳實踐。同時,考慮切換到[Daemontools](http://cr.yp.to/daemontools.html),而不是使用init腳本啓動。 – ghoti

+0

謝謝你的建議,ghoti。我對這兩種提議的解決方案都有功能性的引用。我試圖確定是否存在推薦/標準方法來解決此問題。 – Gary

0

我的解決方案是捕獲命令(通過/proc/PID/cmdline)以及相對開始時間。使用absolute start time(通過ps -p PID -o lstart=)似乎可行,但您會得到confusing results if your system clock changes(例如,來自NTP更新或夏令時)。

這裏是我的實現:

# Prints enough detail to confirm a PID still refers to the same process. 
# In other words, even if a PID is recycled by a call to the same process the 
# output of this command should still be different. This is not guaranteed 
# across reboots. 
proc_detail() { 
    local pid=${1:?Must specify PID} 
    # the process' commandline, if it's running 
    # ensures a non-existant PID will never have the same output as a running 
    # process, and helps debugging 
    cat "/proc/$pid/cmdline" 2> /dev/null && echo 
    # this is the number of seconds after boot that the process started 
    # https://unix.stackexchange.com/a/274722/19157 
    # in theory this could collide if the same process were restarted in the same 
    # second and assigned the same PID, but PIDs are assigned in order so this 
    # seems acceptably unlikely for now. 
    echo "$(($(cut -d. -f1 < /proc/uptime) - \ 
      $(ps -p "$pid" -o etimes= 2> /dev/null || echo "0")))" 
} 

我也決定將這個輸出存儲在/dev/shm讓這對我來說自動清除在關機。還有其他可行的選項(例如@reboot cronjob),但是對於我的用例,寫入tmpfs很簡單且乾淨。