简体   繁体   中英

Linux Fork Process termination

//Executing shell command ls -l | sort
int *pipeIN, *pipeOUT;

int runLS(){
    char* parmListLS[] = { "ls", "-l", NULL };
    int pid = fork();
    if(pid==0){
        close(*pipeIN);
        dup2(*pipeOUT, STDOUT_FILENO);
        execvp(parmListLS[0], parmListLS);
    }else return pid;
}

int runSORT(){
    char* parmListSORT[] = { "sort", NULL };
    int pid = fork();
    if(pid==0){
        close(*pipeOUT);
        dup2(*pipeIN, STDIN_FILENO);
        execvp(parmListSORT[0], parmListSORT);
    }else return pid;
}

int main(void){
    int pidLS, pidSort, pipeId[2];
    pipeIN = &pipeId[0], pipeOUT = &pipeId[1];
    pipe(pipeId); //open pipes

    pidLS = runLS();
    pidSort = runSORT();

    printf("PIDS: LS -> %d, Sort -> %d\n", pidLS, pidSort);
    printf("Terminated: %d\n", wait(NULL)); //return pid of 1st exited proc
    printf("Terminated: %d\n", wait(NULL)); //return pid of 2nd exited proc
    printf("Terminated Main Proccess!\n");
}

Hello! I'm having trouble making some simple pipes work on linux. I'm trying to emulate the shell command ls - l | sort. As you can see, I'm initializing two child proccesses, one for ls -l, and the other for sort. Those proccesses run independently, and I'm trying to redirect the output of ls - l, as input for sort via pipes. The concept is that the main program should wait for both of them to terminate. However, wait seems to work fine for ls -l, but it hangs - never terminates for sort. So the whole program hangs. If I remove the two wait code lines from the program, the ls - l -> sort pipe works perfectly, and of course main terminates before them. I suspect this is due to the fact that sort keeps waiting for input, even after ls - l has terminated. I don't understand how the termination of the parent affects the termination of both children processes. Would anyone please be so kind as to explain to me what actualy happens? Thank you very much. ps. I ignored most error checking for clarity and less code.

The sort can't terminate because the parent process still has the write end (and the read end) of the pipe open, so the sort hasn't reached EOF on the pipe, so it hasn't got all the data, so it can't write any output.

Add:

close(pipeId[0]);
close(pipeID[1]);

after the calls to runLS() and runSORT() and things work as expected.

Ideally, the children should close both ends of the pipe after they've just duplicated. If you duplicate a pipe file descriptor to a standard file stream, you should almost always close both ends of the pipe. In this code, you get away without doing it; that won't always be the case.

Personally, I don't think the two global variables help much. The pipe labelled pipeIn is the input to sort but the output from ls , for example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM