免费注册 查看新帖 |

Chinaunix

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

父进程如何知道孙子进程的pid? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-09 17:03 |只看该作者 |倒序浏览
代码如下:
static INT32 exec_cmd(CHAR  *command, INT32 iTimeOut)
{
    INT32 wait_val ,iRet = START_PROGRAM_FAILED ;
    INT32 pid, timeout ;
    __sighandler_t save_quit, save_int, save_chld;
   
    DWORD    dwTmpTicks  = 0;
    DWORD    dwUsedTicks = 0;
   
    if ((command == 0) && ( iTimeOut <= 0))
        return 1;
   
    timeout  =  iTimeOut / 10 ;
   
    save_quit = signal(SIGQUIT, SIG_IGN);
    save_int  = signal(SIGINT, SIG_IGN);
    save_chld = signal(SIGCHLD, SIG_DFL);
   
    if ((pid = vfork()) < 0)
    {
        signal(SIGQUIT, save_quit);
        signal(SIGINT, save_int);
        signal(SIGCHLD, save_chld);
        return -1;
    }
   
    if (pid == 0)
    {
        signal(SIGQUIT, SIG_DFL);
        signal(SIGINT, SIG_DFL);
        signal(SIGCHLD, SIG_DFL);
        
        execl("/bin/sh", "sh", "-c", command, (char *) 0);
        _exit(127);
    }
    /* Signals are not absolutly guarenteed with vfork */
    signal(SIGQUIT, SIG_IGN);
    signal(SIGINT, SIG_IGN);
   
    dwTmpTicks = GetCurrentTicks();  
    while (1)
    {
        if (wait4(pid, &wait_val, WNOHANG, 0) == -1)          
        {
            if (errno == ECHILD)
            {
                iRet = 0;
                break ;
            }   
        }
        timeout -- ;
        usleep(1);
        if ( 0 >= timeout)
        {
            dwUsedTicks   = GetCurrentTicks() - dwTmpTicks;
            printf(LOG_LEVEL_ERROR,"exec_cmd [%d] : %s use time -- [%d] ticks timeout ! \n",
                           pid, command, dwUsedTicks);
            
            if (0 != kill(pid,SIGKILL))
            {
                printf(LOG_LEVEL_ERROR,"exec_cmd[%d]:kill timeout process[%s]  failed errno[%d]\n",
                               pid,command,errno);
            }
            else
            {
                printf("csp_exec_cmd[%d]:kill timeout process[%s] sucess errno[%d]\n",
                               pid,command,errno);
            }
            
            while(1)
            {
                if (wait4(pid, &wait_val, WNOHANG, 0) == -1)
                {
                    if (errno == ECHILD)
                    {
                        printf("no child exist\n");
                        break;
                    }
                }         
            }        
            
            break;
        }
    }
   
    signal(SIGQUIT, save_quit);
    signal(SIGINT, save_int);
    signal(SIGCHLD, save_chld);
   
    return iRet;
}
这个代码是根据system函数来改写的,就是来达到如果子进程时间很长,我就直接杀掉它退出,
但是问题是execl("/bin/sh", "sh", "-c", command, (char *) 0);这种方式又会fork一个子进程

如果command进程写的是一个死循环的函数,这就会导致父进程只会回收其子进程的资源,其孙子进程
在超时后就变成init的子进程了,然后在那一直循环,这是我所不希望的。
我希望超时后子进程和孙子进程都一起退出。
曾想过用execvp这种方法,但是execvp不支持一些特殊的shell字符,所以有没有方法让父进程知道孙子进程的pid呢?

论坛徽章:
0
2 [报告]
发表于 2009-04-09 17:11 |只看该作者
getpid?

论坛徽章:
0
3 [报告]
发表于 2009-04-09 17:14 |只看该作者
你把它生下来的,你都不知道吗?

论坛徽章:
0
4 [报告]
发表于 2009-04-09 17:15 |只看该作者
关键是在父进程和孙子进程之间一般是不交互的,如果为了个pid交互,这进程间通信的代价~~~

论坛徽章:
0
5 [报告]
发表于 2009-04-09 17:21 |只看该作者
fork()的返回值呢?

论坛徽章:
0
6 [报告]
发表于 2009-04-09 17:28 |只看该作者
execl("/bin/sh", "sh", "-c", command, (char *) 0);
这条命令是先起一个shell,然后shell再fork一个command,这个pid没有地方可以返回啊

论坛徽章:
0
7 [报告]
发表于 2009-04-11 10:32 |只看该作者
后来我在利用cmd中名字,用killall直接把它干掉了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP