cparent-childstdoutfile-readmultiple-processes

Why does my child print a specific line from a file only sometimes?


I am trying to read specific lines from a file using a parent process to read one line and a child process to read some other line. The simple text file has as contents: "This is line one\n", This is line two\n", etc.

However, I find that when I execute my program multiple times, my child does not always print the line from my file. The printf("Entering child\n") does always get executed, indicating that I am able to enter the child process fine.

Why does this work only sometimes?

int main() {
FILE* fptr = fopen("my_text.txt","r");

int stat;
pid_t pid;
int count = 0;
if(fptr != NULL) {
    char line[256];
    fflush(stdout);
    if((pid = fork()) < 0) {
        fprintf(stderr, "fork error: %s\n",strerror(errno));
    }
    else if(pid == 0) {
        printf("entering child\n");
        int lineNumber = 2; // read the second line
        while (fgets(line, sizeof(line), fptr) != NULL) { // loop until we get to desired line
            if (count == lineNumber) {

                printf("CHILD read: %s", line);

                fflush(stdout);
                rewind(fptr);
                break;
            } else {
                count++;
            }
        }
        exit(0); // exit child process

    } else { // parent process

        int lineNumber = 1; 
        while (fgets(line, sizeof(line), fptr) != NULL) { // loop until desired line
            if (count == lineNumber) {
                printf("PARENT read: %s", line);
                fflush(stdout);  
                rewind(fptr);
                break;
            } else {
                count++;
            }
        }
        wait(&stat); // reap the child process
    }
    fclose(fptr);
} else {
    printf("File Does not exist\n");
    exit(0);
}

return 0; }   

From the above code, I sometimes print "This is line two" (from parent) and "This is line three" (from child), or sometimes only "This is line two". The goal is to get both to print.


Solution

  • The two processes share the open file description, which means that they both share the file offset and therefore you have a race condition because they read the file concurrently. There are two ways obvious to fix:

    Other advanced methods would e.g. be to read the file with pread, or mmap it before or after the fork...