Linux daemon进程原理与使用

什么情况下用daemon进程

生产环境下,除了我们ssh登录上去,然后手动跑的那部分以外,其他都是自动运行的,这些大部分都应该是后台执行的。如何才能后台执行呢?

如何选择呢? (1)首先,清理过期日志这一类需求,可以写一个死循环一直运行,,也可以写在crontab里,每次执行完就退出(如果每分钟一次可以满足的话); (2)crontab的需要接受最多1分钟的时延,如果实时性要求更高一些,那么就需要考虑写个死循环了,这个程序可以由crontab来start和restart,只有在挂了重启时才会出现1分钟时延; (3)服务不能中断的(nginx、redis、apache,所有在线服务),一般都是daemon程序。但理论上用(2)似乎也可以;当然这两者细节上有很多区别。

怎么用daemon进程

linux C/C++可以直接调用int daemon(int, int)函数,不需要自己重新实现。 示例代码:

main(int argc, char *argv[]) {if (argc < 3) {printf(“Usage: $0 no_ch_dir no_close_fd\n”);exit(0);}int no_ch_dir = atoi(argv[1]);int no_close_fd = atoi(argv[2]);std::cout << “main pid : ” << getpid() << std::endl;std::cout << “main parent pid : ” << getppid() << std::endl;std::cout << “main pwd : ” << get_current_dir_name() << std::endl;if (daemon(no_ch_dir, no_close_fd) != 0) {::cout << “stdout: daemon = -1” << std::endl;std::cerr << “stderr: daemon = -1” << std::endl;return 1;}std::cout << “stdout: daemon = 0” << std::endl;std::cerr << “stderr: daemon = 0” << std::endl;std::cout << “sub pid : ” << getpid() << std::endl;std::cout << “sub parent pid : ” << getppid() << std::endl;std::cout << “sub pwd : ” << get_current_dir_name() << std::endl;while (1);return 0;}“`编译运行:

[chenming@localhost ~] ./test1 Usage: ./test1 0 0 main pid : 7896 main parent pid : 7573 main pwd : /home/chenming [chenming@localhost ~] ll /proc/7897/fd total 0 lrwx——. 1 chenming chenming 64 May 1 16:15 0 -> /dev/null lrwx——. 1 chenming chenming 64 May 1 16:15 1 -> /dev/null lrwx——. 1 chenming chenming 64 May 1 16:15 2 -> /dev/null [chenming@localhost ~]$ lsof -p 7897 COMMAND PIDUSER FD TYPE DEVICE SIZE/OFF NODE NAME test1 7897 chenming cwd DIR 253,040962 / test1 7897 chenming rtd DIR 253,040962 / test1 7897 chenming txt REG 253,08355 142202 /home/chenming/test1 test1 7897 chenming mem REG 253,0 1906308 38865 /lib/libc-2.12.so test1 7897 chenming mem REG 253,0 122232 52742 /lib/libgcc_s-4.4.7-20120601.so.1 test1 7897 chenming mem REG 253,0 142600 38788 /lib/ld-2.12.so test1 7897 chenming mem REG 253,0 202040 47921 /lib/libm-2.12.so test1 7897 chenming mem REG 253,0 942040 52866 /usr/lib/libstdc++.so.6.0.13 test1 7897 chenming 0u CHR 1,30t0 3903 /dev/null test1 7897 chenming 1u CHR 1,30t0 3903 /dev/null test1 7897 chenming 2u CHR 1,30t0 3903 /dev/null

man 3 daemon可以查看到函数签名:include 也可以自己实现一个:include include include include include include redis里的实现要简单一些(redis.c):

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里的实现(daemon.c):include include include include include “memcached.h”

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(“http://blog.csdn.net/”) != 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);

} “`

我想去旅行,一个人背包,一个人旅行,

Linux daemon进程原理与使用

相关文章:

你感兴趣的文章:

标签云: