打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
用waitpid检测子进程的退出状态

from http://zhoulifa.bokee.com/6614557.html
作者:

下面这个例子显示主进程如何获得子进程的退出状态,以便监测子进程。比如在子进程退出时重新启动它。

源代码是:
/************关于本文档********************************************
*filename: waitpid.c
*purpose: 显示主进程如何获得子进程的退出状态
*wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2008-01-27 19:33 上海大雪天,据说是多年不遇
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to:
*                Ubuntu 本程序在Ubuntu 7.10系统上测试完全正常
*                Google.com 我通常通过google搜索发现许多有用的资料
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/

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

int childprocess(void);
void signalHandle(int signo);

int main(int argc, char ** argv)        {
        pid_t chldpid = 0;
        int status = 0, ret = 0;

        ret = fork();
        if(ret) exit(0);

        ret = fork();
        if(ret < 0)     {printf("exit because fork error! errno:%d %s\n", errno, strerror(errno));exit(1);}
        else if(ret == 0)       {childprocess(); } /* run child process here. */
        else {chldpid = ret; printf("fork ok, child process pid=%d\n", chldpid);}

        while(1)        {
                ret = waitpid(chldpid, &status, WNOHANG);
                if(ret == 0)    {
                        printf("no child process exited now\n");
                }
                else if(ret < 0)        {
                        printf("waitpid error. errno:%d %s\n", errno, strerror(errno));
                        /* if(errno == 10) childprocess(); */ /*如果子进程不存在了,重新启动它? */
                }
                else    {
                        if(WIFEXITED(status))   {
                                printf("child process exited sucessfully,");
                                printf("And it's exited code is:%d\n", WEXITSTATUS(status));
                        }
                        else if(WIFSIGNALED(status))    {
                                printf("child process exited by signal,");
                                printf("And the signal code is:%d\n", WTERMSIG(status));
                        }
                        else if(WCOREDUMP(status))      {
                                printf("child process exited with core dump\n");
                        }
                        else    {
                                printf("child process stopped or resumed\n");
                        }
                }
                usleep(300000);
        }
}

int childprocess(void)  {
        int i = 0;

        signal(SIGUSR1, signalHandle);
        signal(SIGTERM, signalHandle);

        for(i = 1; i < 50; i++) {
                printf("I'm child process, loop.%d\n", i);
                usleep(500000);
        }
        exit(i);
}

void signalHandle(int signo) {
        switch(signo)   {
                case    SIGUSR1:
                        printf("signal SIGUSR1 received! %s\n", strsignal(SIGUSR1));
                break;
                case    SIGTERM:
                        printf("signal SIGTERM received! %s\n", strsignal(SIGTERM));
                break;
                default:
                        printf("other signal received!\n");
        }
}

编译运行此程序:
gcc -Wall waitpid.c
./a.out
可以试着在另一个终端向用kill命令子进程发送一些信号看屏幕输出信息。

当然,如果man waitpid可以看到一个示例代码如下:
       #include <sys/wait.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <stdio.h>

       int
       main(int argc, char *argv[])
       {
           pid_t cpid, w;
           int status;

           cpid = fork();
           if (cpid == -1) {
               perror("fork");
               exit(EXIT_FAILURE);
           }

           if (cpid == 0) {            /* Code executed by child */
               printf("Child PID is %ld\n", (long) getpid());
               if (argc == 1)
                   pause();                    /* Wait for signals */
               _exit(atoi(argv[1]));

           } else {                    /* Code executed by parent */
               do {
                   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 (!WIFEXITED(status) && !WIFSIGNALED(status));
               exit(EXIT_SUCCESS);
           }
       }
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【Linux】进程创建(fork函数)及其等待与退出
UNIX环境编程学习笔记(22)
system函数返回值问题(system的实现)—signal(SIGCHLD,SIG
Linux进程
linux 进程(二)
Linux系统进程控制编程——kill函数使用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服