我的守护进程为啥CPU使用率奇高

samuelo 2010-08-03 09:46:57
写了一个守护进程,运行时CPU使用率奇高,几乎跑满。代码大致如下:

time_t now;
int childpid,fd,fdtablesize;
int error,in,out;
/* 忽略终端 I/O信号,STOP信号 */
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
signal(SIGHUP ,SIG_IGN);
/* 父进程退出,程序进入后台运行 */
if(fork()!=0) exit(1);
if(setsid()<0)exit(1);/* 创建一个新的会议组 */
/* 子进程退出,孙进程没有控制终端了 */
if(fork()!=0) exit(1);
if(chdir("/tmp")==-1)exit(1);
/* 关闭打开的文件描述符,包括标准输入、标准输出和标准错误输出 */
for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++)
close(fd);
umask(0);/*重设文件创建掩模 */
signal(SIGCHLD,SIG_IGN);/* 忽略SIGCHLD信号 */

以上是实现守护进程的代码。之后是自己的代码,省略。
发现如果把代码:
for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++)
close(fd);
中的fd = 0改为fd = 2,那么CPU使用率大大下降,同时终端有输出。
怀疑是close了标准输出所致。但作为守护进程,我想是必须close它的。
之后我做了修改,包括禁用标准输入输出标准错误等,但只要close 标准输入输出和标准错误,CPU使用率就非常高。
请问这是什么原因?
谢谢。

注:我是在终端下用“./守护进程 &”做测试的。



...全文
327 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
samuelo 2010-08-05
  • 打赏
  • 举报
回复
感谢wwwunix。我是多线程程序,没考虑到main也是一个线程。main里没有sleep。
Coder_Granger 2010-08-04
  • 打赏
  • 举报
回复
拿gdb跟一下看看吧,留意fdtablesize是不是超大,或者close老是被中断后重启

守护进程直接调用int daemon(int nochdir, int noclose);不是更方便吗?
Coder_Granger 2010-08-04
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 samuelo 的回复:]

引用 5 楼 coder_granger 的回复:

守护进程直接调用int daemon(int nochdir, int noclose);不是更方便吗?


直接调用daemon,CPU也很高。
[/Quote]

这就说明跟守护进程的创建方式无关了
samuelo 2010-08-04
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 coder_granger 的回复:]

守护进程直接调用int daemon(int nochdir, int noclose);不是更方便吗?
[/Quote]

直接调用daemon,CPU也很高。
wwwunix 2010-08-04
  • 打赏
  • 举报
回复
1、你既然已经在程序中实现了守护进程,就没必要用./守护进程&来执行了。直接./守护进程就可以了。
2、我觉得还是你后面的实现代码有问题,我模拟你的程序执行了一下。结果如下:
2.1、如果代码如后面所示有sleep语句,则CPU的使用率在3%左右。
2.2、如果将代码中的sleep语句去掉,则CPU的使用率在50%左右。
代码如下:

#include <time.h>
#include <signal.h>
int main(int argc,char **argv) {
time_t now;
int childpid,fd,fdtablesize;
int error,in,out,aa;
/* 忽略终端 I/O信号,STOP信号 */
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
signal(SIGHUP ,SIG_IGN);
/* 父进程退出,程序进入后台运行 */
if(fork()!=0) exit(1);
if(setsid()<0)exit(1);/* 创建一个新的会议组 */
/* 子进程退出,孙进程没有控制终端了 */
if(fork()!=0) exit(1);
if(chdir("/tmp")==-1)exit(1);
/* 关闭打开的文件描述符,包括标准输入、标准输出和标准错误输出 */
for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++)
close(fd);
umask(0);/*重设文件创建掩模 */
signal(SIGCHLD,SIG_IGN);/* 忽略SIGCHLD信号 */
while(1) {
aa++;
sleep(10);
}
}
lovebin_bin 2010-08-03
  • 打赏
  • 举报
回复
这个不懂 帮顶了
samuelo 2010-08-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 wenxy1 的回复:]
参考守护进程的写法:http://blog.chinaunix.net/u/12457/showart.php?id=2129402

/* 关闭打开的文件描述符,包括标准输入、标准输出和标准错误输出 */
for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++)
close(fd);

这里错了吧?

……
[/Quote]

这里为啥错?
看了你给的参考,觉得和我的代码基本一样嘛。
Wenxy1 2010-08-03
  • 打赏
  • 举报
回复
参考守护进程的写法:http://blog.chinaunix.net/u/12457/showart.php?id=2129402

/* 关闭打开的文件描述符,包括标准输入、标准输出和标准错误输出 */
for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++)
close(fd);

这里错了吧?
steptodream 2010-08-03
  • 打赏
  • 举报
回复
不太懂
我见过的守护进程 ./守护进程 直接就到后台去了啊

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧