Linux守护进程实现
生活随笔
收集整理的這篇文章主要介紹了
Linux守护进程实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Linux守護進程
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);}
}
memcached版:
int daemonize(int nochdir, int noclose)
{int fd;switch (fork()) {case -1:return (-1);case 0:break;default:_exit(EXIT_SUCCESS);}if (setsid() == -1)return (-1);if (nochdir == 0) {if(chdir("/") != 0) {perror("chdir");return (-1);}}if (noclose == 0 && (fd = open("/dev/null", O_RDWR, 0)) != -1) {if(dup2(fd, STDIN_FILENO) < 0) {perror("dup2 stdin");return (-1);}if(dup2(fd, STDOUT_FILENO) < 0) {perror("dup2 stdout");return (-1);}if(dup2(fd, STDERR_FILENO) < 0) {perror("dup2 stderr");return (-1);}if (fd > STDERR_FILENO) {if(close(fd) < 0) {perror("close");return (-1);}}}return (0);
}
lighttpd版:
#ifdef HAVE_FORK
static void daemonize(void) {
#ifdef SIGTTOUsignal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTINsignal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTSTPsignal(SIGTSTP, SIG_IGN);
#endifif (0 != fork()) exit(0);if (-1 == setsid()) exit(0);signal(SIGHUP, SIG_IGN);if (0 != fork()) exit(0);if (0 != chdir("/")) exit(0);
}
#endif
nginx版:
ngx_int_t
ngx_daemon(ngx_log_t *log)
{int fd;switch (fork()) {case -1:ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed");return NGX_ERROR;case 0:break;default:exit(0);}ngx_pid = ngx_getpid();if (setsid() == -1) {ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed");return NGX_ERROR;}umask(0);fd = open("/dev/null", O_RDWR);if (fd == -1) {ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,"open(\"/dev/null\") failed");return NGX_ERROR;}if (dup2(fd, STDIN_FILENO) == -1) {ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed");return NGX_ERROR;}if (dup2(fd, STDOUT_FILENO) == -1) {ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed");return NGX_ERROR;}#if 0if (dup2(fd, STDERR_FILENO) == -1) {ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed");return NGX_ERROR;}
#endifif (fd > STDERR_FILENO) {if (close(fd) == -1) {ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed");return NGX_ERROR;}}return NGX_OK;
}
注釋版:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>int daemonize(void)
{int fd;switch(fork()) {case -1:return (-1);case 0:break;default://將父進程結束,讓子進程變成真正的孤兒進程,并被init進程接管exit(0);}//子進程成為新的會話組長和新的進程組長,并與原來的登錄會話和進程組脫離setsid();if ((fd = open("daemon.log", O_CREAT|O_RDWR|O_APPEND, 0)) != -1) {//dup2(int oldhandle, int newhandle)復制文件句柄dup2(fd, STDIN_FILENO);dup2(fd, STDOUT_FILENO);dup2(fd, STDERR_FILENO);//0,1和2文件句柄分別與標準輸入,標準輸出,標準錯誤輸出相關聯//所以用戶應用程序調用open函數打開文件時,默認都是以3索引為開始句柄//fd已經由新的句柄代替,關閉fd句柄if (fd > STDERR_FILENO) (void)close(fd);}return 0;
}int main(int argc, char *argv[])
{daemonize();printf("%s\n","hello");return 0;
}
# cc daemonize.c -o daemonize
#?./daemonize
# ps aux | grep daemonize
參考:
http://blog.linuxphp.org/archives/1476/
http://www.cnblogs.com/xuxm2007/archive/2011/07/29/2121280.html
http://blog.csdn.net/yyyzlf/article/details/5267954
http://docs.linuxtone.org/ebooks/C&CPP/c/ch34s03.html
總結
以上是生活随笔為你收集整理的Linux守护进程实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 结构体的两种声明方式:堆上和栈上以及在双
- 下一篇: 仿照redis写的nginx开机画面