其他人也有同樣的問題。見this gist。
當daemonize選項被激活時,Redis不檢查進程是否已經是守護進程(沒有調用getppid)。它系統地分叉,但只有一次。有點不尋常,其他守護進程機制可能需要對getppid進行初始檢查,並且fork被調用兩次(在setsid調用之前和之後),但在Linux上這不是嚴格要求的。
有關守護進程的更多信息,請參見this faq。
Redis的守護進程的功能是非常簡單的:
void daemonize(void) {
int fd;
if (fork() != 0) exit(0); /* parent exits */
setsid(); /* create a new session */
/* Every output goes to /dev/null. If Redis is daemonized but
* the 'logfile' is set to 'stdout' in the configuration file
* it will not log at all. */
if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
if (fd > STDERR_FILENO) close(fd);
}
}
新貴文件說:
expect daemon
Specifies that the job's main process is a daemon, and will fork twice after being run.
init(8) will follow this daemonisation, and will wait for this to occur before running
the job's post-start script or considering the job to be running.
Without this stanza init(8) is unable to supervise daemon processes and will
believe them to have stopped as soon as they daemonise on startup.
expect fork
Specifies that the job's main process will fork once after being run. init(8) will
follow this fork, and will wait for this to occur before running the job's post-start
script or considering the job to be running.
Without this stanza init(8) is unable to supervise forking processes and will believe
them to have stopped as soon as they fork on startup.
所以我無論是在Redis的一側關閉系統守護進程,或者嘗試使用期望叉,而不是指望守護進程新貴配置。
感謝您的答覆。我的strace研究以及正常觀察表明,Redis分叉兩次。閱讀代碼,我不明白這是如何可能的,但不知何故似乎。另外,我確實嘗試了「期望分叉」,並且沒有找到正確的PID。我看到了Gist,但我們永遠不能相信其他人已經做了深入的作業來解決根本問題。我認爲守護進程不適合Upstart。 – 2011-12-30 15:49:50
我剛剛在守護進程的實例上嘗試了一個簡單的strace -f src/redis-server redis.conf 2> strace.log,並且它只分叉一次。請注意,在Linux上,克隆系統調用用於創建進程和線程(Redis現在使用幾個後臺線程)。參數應該清楚它是一個線程還是一個進程。太糟糕了「期望叉」不能像我們預期的那樣工作...... – 2011-12-30 16:55:05
好吧,謝謝你確認它是一個單叉。我絕對嘗試過「期待叉」並沒有取得成功,但我可以再做一次以確保它的正確性。我會回報。 – 2011-12-30 17:07:15