0

我正在尝试使用父进程读取文件中的特定行来读取一行,并使用子进程读取其他行。简单文本文件的内容为:“这是第一行\n”、这是第二行\n”等。

但是,我发现当我多次执行我的程序时,我的孩子并不总是从我的文件中打印该行。printf("Entering child\n") 总是被执行,表明我可以正常进入子进程。

为什么这只是有时有效?

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

从上面的代码中,我有时会打印“这是第二行”(来自父级)和“这是第三行”(来自子级),或者有时只打印“这是第二行”。目标是让两者都打印出来。

4

1 回答 1

4

这两个进程共享打开的文件描述,这意味着它们都共享文件偏移量 ,因此您有一个竞争条件,因为它们同时读取文件。有两种明显的修复方法:

  • 使用一些 IPC 机制进行同步,或文件描述锁定- 参见示例flock
  • 在fork之后的每个进程中打开文件。

其他高级方法例如是使用pread, 或者mmap在 fork 之前或之后读取文件...

于 2019-12-01T19:42:55.027 回答