9

如果在命令末尾找到“&”,我正在尝试模仿在后台运行进程的 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,我希望它在后台运行进程,告诉我它已经创建了进程..然后提示接受下一个命令。

4

2 回答 2

6

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

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

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

于 2013-01-27T14:50:05.360 回答
4

这很简单。假设您有一个进程 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);
}

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

于 2013-01-27T15:10:52.257 回答