Chinaunix

标题: 父进程如何知道孙子进程的pid? [打印本页]

作者: linkejin    时间: 2009-04-09 17:03
标题: 父进程如何知道孙子进程的pid?
代码如下:
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呢?
作者: prolj    时间: 2009-04-09 17:11
getpid?
作者: 雨过白鹭洲    时间: 2009-04-09 17:14
你把它生下来的,你都不知道吗?
作者: linkejin    时间: 2009-04-09 17:15
关键是在父进程和孙子进程之间一般是不交互的,如果为了个pid交互,这进程间通信的代价~~~
作者: prolj    时间: 2009-04-09 17:21
fork()的返回值呢?
作者: linkejin    时间: 2009-04-09 17:28
execl("/bin/sh", "sh", "-c", command, (char *) 0);
这条命令是先起一个shell,然后shell再fork一个command,这个pid没有地方可以返回啊
作者: linkejin    时间: 2009-04-11 10:32
后来我在利用cmd中名字,用killall直接把它干掉了




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2