Goktug Asked: 2018-03-05 03:14:47 +0800 CST2018-03-05 03:14:47 +0800 CST 2018-03-05 03:14:47 +0800 CST 文件操作和流程 772 两个不同的进程(父进程和子进程)是否有可能看到同一个文本文件并对其进行操作? 我完成了这个,但我必须使用 fopen() 在两个进程中打开文件。我的期望是其中一个进程打开文件,而另一个进程可以查看和操作它。 files process 2 个回答 Voted Best Answer Kusalananda 2018-03-05T03:20:35+08:002018-03-05T03:20:35+08:00 从我的 OpenBSD 系统的fork(2)手册中(我的重点): 子进程拥有自己的父描述符副本。这些描述符引用相同的底层对象,例如,文件对象中的文件指针在子进程和父进程之间共享,因此lseek(2)子进程中的描述符可以影响后续进程read(2) 或write(2)父进程。shell 也使用此描述符复制来为新创建的进程建立标准输入和输出以及设置管道。 这意味着如果您在分叉子进程之前在父进程中打开一个文件,两个进程将打开同一个文件。但是,如果孩子从文件中读取,那么父母的文件指针也将被移动。 要在两个进程中分别访问文件,您必须分别在两个进程中打开文件。 如果调用后fork()在父进程中打开文件,子进程将不会打开该文件,反之亦然。 thrig 2018-03-05T07:29:22+08:002018-03-05T07:29:22+08:00 这是一些可以做到这一点的示例代码。 #include <err.h> #include <stdio.h> #include <unistd.h> char buf[8]; int main(int argc, char *argv[]) { int ch, fd[2], rv; pipe(fd); switch (fork()) { case -1: err(1, "could not fork"); case 0: // child rv = lseek(STDIN_FILENO, -7, SEEK_END); if (rv == -1) err(1, "could not seek"); sleep(3); close(fd[1]); break; default: // parent close(fd[1]); read(fd[0], &ch, 1); read(STDIN_FILENO, buf, 7); printf("read '%s'\n", buf); } return 0; } 发生的事情是父母阻止等待孩子,同时孩子寻求标准输入的结尾,减七,然后关闭pipe(2)父母。这解除了父级的阻塞,父级从共享描述符中读取子级将共享文件指针移动到的位置。 $ make sharedseek cc sharedseek.c -o sharedseek $ echo asdfasdfasdf123456 > x $ ./sharedseek < x read '123456 ' $ 如果标准输入不可搜索,这将不起作用。此外,管道(或某种形式的通信)确实是必要的,否则父母可能会在孩子之前运行。 如果文件描述符未共享,则父级将不会从子级将指针移动到的位置读取。
从我的 OpenBSD 系统的
fork(2)
手册中(我的重点):这意味着如果您在分叉子进程之前在父进程中打开一个文件,两个进程将打开同一个文件。但是,如果孩子从文件中读取,那么父母的文件指针也将被移动。
要在两个进程中分别访问文件,您必须分别在两个进程中打开文件。
如果调用后
fork()
在父进程中打开文件,子进程将不会打开该文件,反之亦然。这是一些可以做到这一点的示例代码。
发生的事情是父母阻止等待孩子,同时孩子寻求标准输入的结尾,减七,然后关闭
pipe(2)
父母。这解除了父级的阻塞,父级从共享描述符中读取子级将共享文件指针移动到的位置。如果标准输入不可搜索,这将不起作用。此外,管道(或某种形式的通信)确实是必要的,否则父母可能会在孩子之前运行。
如果文件描述符未共享,则父级将不会从子级将指针移动到的位置读取。