【问题标题】:Using waitpid to run process in background?使用waitpid在后台运行进程?
【发布时间】:2013-01-10 23:38:00
【问题描述】:

如果在命令末尾找到“&”,我正在尝试模仿后台运行进程的 bash 功能。我有以下功能......我不认为它正在做我想要它做的事情

int execute(char* args[],int background,int *cstatus){
    pid_t   child;
    pid_t   ch;                         /*Pid of child returned by wait*/
    if ((child = fork()) == 0){                 /*Child Process*/
        execvp(args[0],args);       
        fprintf(stderr, "RSI: %s: command not found\n",args[0]); /*If execvp failes*/
        exit(1);

    }else{          /*Parent process*/
        if (child== (pid_t)(-1)) {
            fprintf(stderr,"Fork failed\n"); exit(1);
        }else{
            if (background==0){             /*If not running in background..wait for process to finish*/
                ch = wait(cstatus);
            }else{
                printf("%ld Started\n",(long)getpid());
        /*  printf("Parent: Child %ld exited with status = %ld\n", (long) ch, (long)cstatus);
    */  }}
    }
return 0;
}
int wait_and_poll(int *cstatus){
    pid_t status;
    status = waitpid(-1,cstatus,WNOHANG);
    if (status>0){
        fprintf(stdout,"%ld Terminated.\n",(long) status);
    }
return 0;
}

如果我只是运行“ls -l”,它会按预期工作..但是如果我想在后台运行 ls..并且让程序继续接受新命令,我会调用该函数并将背景标志设置为 1,然后我希望它在后台运行进程,告诉我它已经创建了进程..然后提示接受下一个命令。

【问题讨论】:

    标签: c process waitpid


    【解决方案1】:

    这很简单。 假设您有一个进程 P,其 id 为 pid。

    如果你想让它在后台运行(可以在你输入到 shell/program 的字符串末尾的 & 识别),你应该这样做

    //some code
    id=fork();
    if(id==0)
    {
    //child does work here
    }
    else
    {
    //Parent does work here
    if(!strcmp(last string,"&")==0)waitpid(id,&status,0);
    }
    

    因此,如果您请求后台执行,父级不会等待,否则它会等待。

    【讨论】:

    • 但是,jobs 功能不适用于此解决方案。
    【解决方案2】:

    我不认为waitpid(-1, &cstatus, WNOHANG); 做你认为它做的事。您需要检查它的返回值。如果是> 0,那就是已经退出的子进程的PID。如果是0 或-1,则没有子进程改变状态。

    您可以在运行每个命令之前和/或之后调用waitpid(-1, &cstatus, WNOHANG);。在循环中调用它以捕获多个子出口。

    您也可以处理 SIGCHILD。您的进程将在子进程退出后立即收到此信号,如果您想立即报告子进程终止,而不等待用户输入,这很好。

    【讨论】:

    • 如果我有超过 1 个后台进程正在运行,我是否需要存储它们的 pid 并使用 waitpid 循环遍历它们?
    • 绝对不是。致电waitpid(-1, &cstatus, WNOHANG)。这将提供您需要的所有信息。
    • 我更新了代码,现在我在execute方法之前和之后调用wait_and_poll方法。但是状态永远不会> 0,对我来说总是-1或0?即使我关闭了我在后台启动的程序..或者在它上面使用 Kill。
    • 我不确定为什么会发生这种情况。如果waitpid返回-1,errno的值是多少?你确定没有给wait 和其他地方的朋友打电话吗?
    • 我有一个与waitpid 完全一致的示例程序,请参阅pastebin。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 2014-05-29
    • 2023-03-10
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多