免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6795 | 回复: 13
打印 上一主题 下一主题

关于apue2守护进程的daemonize函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-30 11:22 |只看该作者 |倒序浏览
程序见附件,代码来自apue第二版,守护进程那一章,程序清单13-1,我加了一些printf语句供调试用,
其中有一个for循环,用来关闭文件描述符:
        if (rl.rlim_max == RLIM_INFINITY)
                rl.rlim_max = 1024;
        for (i = 0; i < rl.rlim_max; i++) {
                printf("i = %d\n", i);
                close(i);
        }
        printf("max descriptor: %d\n", rl.rlim_max);

很奇怪,从运行结果来看,执行到 i 等于 2,也就是关闭文件描述符2时,程序莫名其妙的退出。以下是运行结果:
apue2> gcc -g daemonize.c libapue.a
apue2> ./a.out
the first child begin...
the second child begin...
i = 0
i = 1

daemonize.tar.gz

12.48 KB, 下载次数: 74

论坛徽章:
0
2 [报告]
发表于 2009-03-30 11:36 |只看该作者
你把标准输出关闭了,自然就看不到输出了。。

论坛徽章:
0
3 [报告]
发表于 2009-03-30 12:21 |只看该作者

回复 #2 maxxfire 的帖子

哦,真是恍然大悟,我还有几个个地方不明白:
书上说运行a.out后,用ps -axj可以查看该守护进程的状态,但我这样做看不到关于a.out的进程信息啊?
另外这个守护进程的作用是什么?它运行后我怎么和它交互呢?在main函数里调用daemonize("uptime")后,是否会运行uptime这个命令呢?

[ 本帖最后由 kenby 于 2009-3-30 12:26 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-03-30 14:02 |只看该作者
守护进程里一般都是死循环,ps中看不到该进程,应该是你的进程一下子就结束了,在代码后面加上pause看看。

daemonize参数的作用,你看看代码应该能明白吧。

论坛徽章:
0
5 [报告]
发表于 2009-03-30 14:59 |只看该作者

回复 #4 Sorehead 的帖子

大概明白了,麻烦你再看看这段程序:
#include <syslog.h>
int main()
{
        int test = 10;
        openlog("MySysLogTest", LOG_PID|LOG_CONS, LOG_LOCAL7);
        syslog(LOG_LOCAL7|LOG_ERR, "ERROR: just my test error msg syslog(test val=%d)\n", test);
        closelog();
        return 0;
}
按理说这段程序会产生一条记录,我找遍了/var/log目录下的记录文件都没有找到这条记录啊。

论坛徽章:
0
6 [报告]
发表于 2009-03-30 20:38 |只看该作者
APUE第2版的这段代码纯粹狗尾续貂,忽视之!
用现成的库函数:

man daemon

论坛徽章:
0
7 [报告]
发表于 2009-03-30 21:34 |只看该作者

回复 #6 JohnBull 的帖子

恩,的确,apue2的daemonize函数在我这运行总是有问题,用库函数daemon就可以创建守护进程。不过apue2给我们演示了
创建守护进程的过程。谢谢Sorehead及版主

论坛徽章:
0
8 [报告]
发表于 2009-03-31 10:19 |只看该作者
原帖由 kenby 于 2009-3-30 21:34 发表
恩,的确,apue2的daemonize函数在我这运行总是有问题,用库函数daemon就可以创建守护进程。不过apue2给我们演示了
创建守护进程的过程。谢谢Sorehead及版主


如果你想了解创建守护进程的过程,请看第一版的APUE,Stevens写的函数没有问题,简短清晰。
APUE2的代码画蛇添足到达了相当的境界...

论坛徽章:
0
9 [报告]
发表于 2009-03-31 14:45 |只看该作者
apue2的damemonize是没有问题,先前是我粗心写错了一个变量名,检查了好久才检查出来。
apue1上用的是daemon_init这个函数吧,实现了主要的功能,但过于简陋吧
1.没有关闭从父进程继承而来的文件描述符
2.没有为守护进程提供错误记录
3.没有把STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO打开到/dev/null
这些功能好像也不是必须的
顺便问一下版主,调用syslog(LOG_ERR, "ruptimed: fork error")会把错误信息记录到哪个文件啊?

论坛徽章:
0
10 [报告]
发表于 2009-03-31 23:39 |只看该作者
原帖由 kenby 于 2009-3-31 14:45 发表
1.没有关闭从父进程继承而来的文件描述符
2.没有为守护进程提供错误记录
3.没有把STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO打开到/dev/null


说他狗尾续貂绝非冤枉!

1 为什么要关闭从父进程继承而来的所有文件描述符?如果在daemonize之前调用了openlog()的话难道要再openlog()一次?折腾不折腾啊?没用的描述符你关闭,有用的难道你也关闭???(想起来一件事:曾经去一家相当不小的公司(不点名了)洽谈培训事宜,来了个号称技术总监的货,他问我写daemon的时侯出现broken pipe是因为什么,我很蒙,我哪知道为什么!他得意洋洋地解释说“你做daemon的时侯肯定要关闭所有文件描述符吧...”,一句话我就懂了,这丫的肯定照抄apue2扫射关闭文件描述符来的,不好意思打击他,也没义务纠正他...)

2 和 3 这两件事情是成为daemon的必要操作吗?不是!
apache就没有使用syslog啊!谁说STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO一定要重定向到null了?别处不行吗??

还有:为什么要忽略SIGHUP?不知道很多daemon要使用SIGHUP重装载配置文件吗?
...

把这些不必要的操作放在一个公共函数中合理吗?仔细考虑考虑APUE1里面为什么不写这些东西!难道是Stevens不明白吗?

一个程序员能够明白不做什么,与明白做什么一样重要!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP