一个看门狗的理解

yaxf999 2011-10-12 03:12:11
下面这段代码,不知道怎么理解:

int Watching()
{
pid_t cpid, w;
int status;

do
{
cpid = fork();
if(cpid == - 1)
{
printf("fork error!\n");
exit(EXIT_FAILURE);
}

if(cpid == 0)
{
printf("Child PID is %ld\n", (long)getpid());
return 0;
}

w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
if(w == - 1)
{
perror("waitpid");
exit(EXIT_FAILURE);
}

if(WIFEXITED(status))
{
printf("exited, status=%d\n", WEXITSTATUS(status));
}
else if(WIFSIGNALED(status))
{
printf("killed by signal %d\n", WTERMSIG(status));
}
else if(WIFSTOPPED(status))
{
printf("stopped by signal %d\n", WSTOPSIG(status));
}
else if(WIFCONTINUED(status))
{
printf("continued\n");
}
}while(15 != WTERMSIG(status));

exit(EXIT_SUCCESS);

return 1;
}
有人能帮忙解释不?
...全文
194 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
5t4rk 2011-10-12
  • 打赏
  • 举报
回复
楼上的大侠们

qq120848369 2011-10-12
  • 打赏
  • 举报
回复
WIFEXITED(stat_val)

Evaluates to a non-zero value if status was returned for a child process that terminated normally.

WEXITSTATUS(stat_val)

If the value of WIFEXITED(stat_val) is non-zero, this macro evaluates to the low-order 8 bits of the status argument that
the child process passed to _exit() or exit(), or the value the child process returned from main().

WIFSIGNALED(stat_val)

Evaluates to a non-zero value if status was returned for a child process that terminated due to the receipt of a signal
that was not caught (see <signal.h>).

WTERMSIG(stat_val)

If the value of WIFSIGNALED(stat_val) is non-zero, this macro evaluates to the number of the signal that caused the termi‐
nation of the child process.

WIFSTOPPED(stat_val)

Evaluates to a non-zero value if status was returned for a child process that is currently stopped.

WSTOPSIG(stat_val)

If the value of WIFSTOPPED(stat_val) is non-zero, this macro evaluates to the number of the signal that caused the child
process to stop.

WIFCONTINUED(stat_val)

Evaluates to a non-zero value if status was returned for a child process that has continued from a job control stop.


上边贴错了。。
qq120848369 2011-10-12
  • 打赏
  • 举报
回复
The options argument is constructed from the bitwise-inclusive OR of zero or more of the following flags, defined in the
<sys/wait.h> header:

WCONTINUED
The waitpid() function shall report the status of any continued child process specified by pid whose status has not been
reported since it continued from a job control stop.

WNOHANG
The waitpid() function shall not suspend execution of the calling thread if status is not immediately available for one of
the child processes specified by pid.

WUNTRACED
The status of any child processes specified by pid that are stopped, and whose status has not yet been reported since they
stopped, shall also be reported to the requesting process.
qq120848369 2011-10-12
  • 打赏
  • 举报
回复
cpid是孩子的pid,而且子进程已经跑进if(cpid==0)了,父进程掠过这一句运行到waitpid.

子进程return,父进程waitpid返回然后查一下状态。

The options argument is constructed from the bitwise-inclusive OR of zero or more of the following flags, defined in the
<sys/wait.h> header:

WCONTINUED
The waitpid() function shall report the status of any continued child process specified by pid whose status has not been
reported since it continued from a job control stop.

WNOHANG
The waitpid() function shall not suspend execution of the calling thread if status is not immediately available for one of
the child processes specified by pid.

WUNTRACED
The status of any child processes specified by pid that are stopped, and whose status has not yet been reported since they
stopped, shall also be reported to the requesting process.
yaxf999 2011-10-12
  • 打赏
  • 举报
回复
谢谢各位大侠,我终于搞懂这个小函数的作用了。子进程是运行程序,当子进程退出时,主进程可以重启程序。测试代码如下:

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int Watching()
{
pid_t cpid, w;
int status;

do
{
cpid = fork();
if(cpid == - 1) //进程创建失败
{
printf("fork error!\n");
exit(EXIT_FAILURE);
}

if(cpid == 0) // 子进程
{
printf("Child PID is %ld\n", (long)getpid());
//sleep(3600);
return 0;
}

w = waitpid(cpid, &status, WUNTRACED | WCONTINUED); // 父进程
// printf("wait: %d here pid is: %d\n",cpid,getpid() );
if(w == - 1)
{
perror("waitpid");
exit(EXIT_FAILURE);
}

if(WIFEXITED(status)) // 子进程正常结束
{
printf("exited, status=%d\n", WEXITSTATUS(status));
}
else if(WIFSIGNALED(status)) // 子进程因为信号结束
{
printf("killed by signal %d\n", WTERMSIG(status)); // 取得信号代码
}
else if(WIFSTOPPED(status)) // 子进程处于暂停执行情况 (需要用: WUNTRACED)
{
printf("stopped by signal %d\n", WSTOPSIG(status)); // 取得引起暂停的信号代码
}
else if(WIFCONTINUED(status)) // also return if a stopped child has been resumed by delivery of SIGCONT.
{
printf("continued\n");
}
}while(15 != WTERMSIG(status)); // #define SIGTERM 15 如果不是SIGTERM信号,则继续循环 (收到终端信号的进程)

exit(EXIT_SUCCESS);

return 1;
}

int main()
{
Watching();
do
{
printf("runing...\n");
sleep(1);
break;
} while (1);

}

luciferisnotsatan 2011-10-12
  • 打赏
  • 举报
回复
fork函数调用一次,返回两次。
父进程里返回创建的子进程PID,而子进程里则返回0
所以在运行到
if(cpid == 0) // 子进程
后,父子进程各自运行不同的代码。


lz如果不清楚fork这个函数的话,还是先找本《linux程序设计》或《unix环境高级编程》看下相关章节吧
yaxf999 2011-10-12
  • 打赏
  • 举报
回复
请问各位,这段代码在一个程序中,有什么作用? 
yaxf999 2011-10-12
  • 打赏
  • 举报
回复
w = waitpid(cpid, &status, WUNTRACED | WCONTINUED); 这里只有父进程能运行到这儿? 这里的cpid是父进程的进程号吗?
luciferisnotsatan 2011-10-12
  • 打赏
  • 举报
回复
if(cpid == 0) // 子进程
{
printf("Child PID is %ld\n", (long)getpid());
sleep(120);
return 0;
}

加个sleep,然后运行程序。看到子进程PID后,杀了/暂停子进程。看看各种不同的输出。
原来代码里直接return,你应该没法看到正常情况外的退出。
yaxf999 2011-10-12
  • 打赏
  • 举报
回复
我的理解如下: 就是不知道怎么工作。
int Watching()
{
pid_t cpid, w;
int status;

do
{
cpid = fork();
if(cpid == - 1) //进程创建失败
{
printf("fork error!\n");
exit(EXIT_FAILURE);
}

if(cpid == 0) // 子进程
{
printf("Child PID is %ld\n", (long)getpid());
return 0;
}

w = waitpid(cpid, &status, WUNTRACED | WCONTINUED); // 父进程
if(w == - 1)
{
perror("waitpid");
exit(EXIT_FAILURE);
}

if(WIFEXITED(status)) // 子进程正常结束
{
printf("exited, status=%d\n", WEXITSTATUS(status));
}
else if(WIFSIGNALED(status)) // 子进程因为信号结束
{
printf("killed by signal %d\n", WTERMSIG(status)); // 取得信号代码
}
else if(WIFSTOPPED(status)) // 子进程处于暂停执行情况 (需要用: WUNTRACED)
{
printf("stopped by signal %d\n", WSTOPSIG(status)); // 取得引起暂停的信号代码
}
else if(WIFCONTINUED(status)) // also return if a stopped child has been resumed by delivery of SIGCONT.
{
printf("continued\n");
}
}while(15 != WTERMSIG(status)); // #define SIGTERM 15 如果不是SIGTERM信号,则继续循环 (收到终端信号的进程)

exit(EXIT_SUCCESS);

return 1;
}
Qlaiaqu 2011-10-12
  • 打赏
  • 举报
回复
楼主,你先了解一下linux下的创建进程函数fork和子进程退出等待函数waitpid这两个基础函数再说,不然别人说你也不懂
modicum_lf 2011-10-12
  • 打赏
  • 举报
回复

创建进程 并且判断statu !
那些宏都是定义好的 !专门用来判断的 !
luciferisnotsatan 2011-10-12
  • 打赏
  • 举报
回复
很基本的unix/linux上的代码。找本 unix环境高级编程 看看

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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