2010-11-08 37 views
2

我正在設計一個監視進程。監視過程的任務是監視幾組配置的過程。當監視進程檢測到進程已經停止時,它需要重新啓動進程。設計用於監視和重新啓動進程的監視進程

我正在開發我的linux系統的代碼。下面是我如何開發一個小樣機 - 提供有關需要監控的各種流程的詳細信息(路徑,參數)。 - 監控進程執行以下操作: 1.安裝SIGCHLD的信號處理程序 2.使用fork和execv啓動要監控的進程。存儲子進程的PID。 3.當孩子失蹤時,家長會收到SIGCHLD 4.現在會調用信號處理程序。處理程序將在之前存儲的pid列表上運行for循環。對於每個pid,它將檢查/ proc文件系統是否存在與pid對應的目錄。如果該目錄不存在,則重新啓動該過程。

現在,我的問題是這樣的 - 上述方法(檢查/ proc文件系統)檢查標準或推薦的機制檢查進程是否正在運行,或者我應該做一些事情,如爲ps命令創建管道和循環通過ps的輸出? - 有沒有更好的方法來達到我的要求?

問候。

回答

0

通過向其pid發出一個kill()系統調用,您可以輕鬆判斷進程是否處於活動狀態。如果孩子沒有活着,kill()將不會成功。

另外,如果進程仍然存在,那麼調用waitpid()WNOHANG選項將立即返回零。

恕我直言,讀取proc文件或管道到PS是一個討厭的方式來做到這一點。

+0

我希望我的主要工作儘可能少的工作,以便cpu資源不被它消耗。在這種情況下,上述解決方案不會更好嗎? (在信號處理程序中執行waitpid並在主要休眠) – user500949 2010-11-09 02:48:34

2

讓我們來看看我是否理解你。你有一個孩子的列表,你正在你的SIGCLD處理程序上運行一個/ proc循環來查看哪些孩子還活着,不是嗎?

這不是很平常,...這是一個醜陋,

你通常是在你的SIGCLD處理程序運行什麼while((pid = waitpid(-1, &status, WNOHANG)))迴路,並使用返回的PID和WXXX宏來維持你的孩子名單最新。

請注意wait()waitpid()是異步信號安全的。您打電話來檢查/proc的功能可能不是。

+2

如果你只是在等待子進程,你不需要在信號處理程序中這樣做。只需要調用waitpid而不用WNOHANG,並且您不必走異步信號的安全線。 – nos 2010-11-09 01:08:50

+0

恕我直言,在信號處理程序中有一個waitpid會更好,因爲我可以在其中執行一個while(1)循環,其中有睡眠(100)。這樣,我的主要通常會睡覺,不消耗任何CPU週期。你說什麼 ? – user500949 2010-11-09 02:44:04

+0

@ user500949:如果你的程序沒有做任何其他的事情,'waitpid()'不帶'WNOHANG'會阻塞(睡眠)。另一方面,如果你在你的程序中做了其他的事情,並且可以做所有事情來監視文件描述符並等待超時(使用'poll()','select()'或者等價的),你可以使用自我管理技巧將一個SIGCLD變成一個可從文件描述符中看到的事件。 – ninjalj 2010-11-09 09:27:40

4

您不應該檢查/proc以確定哪個進程已退出 - 另一個無關的進程可能在此期間啓動,並且被巧合地分配給相同的PID。

相反,你SIGCHLD處理程序中,你應該使用waitpid()系統調用,在一個循環中,如:

int status; 
pid_t child; 

while ((child = waitpid(-1, &status, WNOHANG)) > 0) 
{ 
    /* Process with PID 'child' has exited, handle it */ 
} 

(需要循環,因爲多個子進程可能會很短的時間內退出,但只會產生一個SIGCHLD)。

+0

我想這看起來像一個正確的方法來做到這一點,因爲在這種情況下,我可以有我的主要執行一段時間(1)循環與睡眠(100)在裏面。當孩子退出時,我使用waitpid來確定哪一個退出並重新啓動該過程。這樣我的主循環不會消耗太多資源(大部分時間它都會處於休眠狀態)。該進程只會處理一個SIGCHLD(重啓進程)並重新進入睡眠狀態。 – user500949 2010-11-09 02:42:18

+0

@ user500949:由於@nos在另一條評論中提到,如果你打算這樣做,那麼只需將上面的循環放在'main()'中,然後刪除'WNOHANG'標誌。 'waitpid()'然後會休眠,直到進程退出,這正是你想要的。 – caf 2010-11-09 04:15:31