日期:2014-05-16  浏览次数:20548 次

执行一个外部程序,什么时候必须用fork+execl而不能直接system()?
system函数里面可以"PATH=.... /usr/local/bin/my..."这样去设置PATH或者别的环境变量。

那么有没有什么情形,执行一个外部命令,必须用fork+execl而不能直接system()的?
谢谢

------解决方案--------------------
system 是 fork/exec 的一个 wrapper, 灵活性不如 fork,

------解决方案--------------------
你想不阻塞,手动回收子进程的时候 waitpid
system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。

看下system的实现,调用system后 父进程会阻塞在 waitpid上

int system(const char * cmdstring)
{
    pid_t pid;
    int status;
 
if(cmdstring == NULL)
{
    return (1); //如果cmdstring为空,返回非零值,一般为1
}

if((pid = fork())<0)
{
    status = -1; //fork失败,返回-1
}
else if(pid == 0)
{
    execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
    _exit(127); // exec执行失败返回127,注意exec只在失败时才返回现在的进程,成功的话现在的进程就不存在啦~~
}
else //父进程
{
    while(waitpid(pid, &status, 0) < 0)
    {
        if(errno != EINTR)
        {
            status = -1; //如果waitpid被信号中断,则返回-1
            break;
        }
    }
}
 
    return status; //如果waitpid成功,则返回子进程的返回状态
}