为什么我的 child 有时只打印文件中的特定行?

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

我正在尝试使用 parent 进程读取一行并使用 child 进程读取其他行来从文件中读取特定行。简单文本文件的内容为:"This is line one\n",这是行 two\n”,等等

但是,我发现当我多次执行我的程序时,我的 child 并不总是打印我文件中的行。 printf("Entering child\n") 确实总是被执行,表明我能够正常进入 child 过程。

为什么这只是有时有效?

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; }   

根据上面的代码,我有时会打印 "This is line two"(来自 parent)和 "This is line three"(来自 child),或者有时只打印 "This is line two"。目标是让两者都打印出来。

两个进程共享打开文件描述,也就是说它们都共享文件偏移量 因此你有一个竞争条件,因为他们并发读取文件。有两种明显的修复方法:

  • 使用一些 IPC 机制进行同步,或文件描述 locks - 例如参见 [​​=10=].
  • 在fork后的每个进程中打开文件。

其他高级方法例如是用 preadmmap 在 fork 之前或之后读取文件...