【问题标题】:Linux - Disabing buffered I/O to file in the child processesLinux - 禁用缓冲 I/O 到子进程中的文件
【发布时间】:2011-10-17 23:53:51
【问题描述】:

在我的应用程序中,我正在创建一堆子进程。在 fork() 之后,我打开一个每个进程的文件,将创建的进程的 stdout/stderr 设置为指向该文件,然后执行预期的程序。

父进程是否可以设置这样一种方式,即当子进程执行 printf 时,它会立即刷新到输出文件而无需调用 flush() ?或者是否有可以从子进程本身调用的 API(在 exec 之前)以禁用缓冲 I/O?

【问题讨论】:

  • 查看 setvbuf 的手册页,您可以将 stdout 设置为无缓冲。 stderr 已设置为无缓冲。

标签: linux buffering


【解决方案1】:

这里的问题是printf 被缓冲了。底层文件描述符不是以这种方式缓冲的(它们在内核中缓冲,但另一端可以从同一个内核缓冲区中读取)。您可以使用 setvbuf 更改缓冲,如评论中所述,这应该是一个答案。

setvbuf(stdout, NULL, _IONBF, 0);

您不需要为stdinstderr 执行此操作。

您不能从父进程执行此操作。这是因为缓冲区是由子进程创建的。父进程只能操作底层文件描述符(位于内核中),不能操作stdout(它是C 库的一部分)。

P.S.你的意思是fflush,而不是flush

【讨论】:

  • 这个答案大部分是正确的。除了“在内核中缓冲”。 stdio 工具,printf()setvbuf() 是其中的一部分,在 libc 中缓冲。缓冲在内核中的是管道和 fifo,但问题明确指出发生了对文件的重定向。 IOW,如果可以修改子进程,则应在子进程的 main 开头添加对 stdout 上的setvbuf() 的调用。 (stderr 默认不缓冲。)
  • @Dummy00001:所有 IO 都在内核中缓冲,除非你使用像 O_DIRECT 这样的扩展名,在这种情况下,它仍然会在写入之前被磁盘缓冲。
  • 看起来 setvbuf() 没有在 exec 中保留?我有这样的东西.. if (fork() == 0) { setvbuf() exec() } printf 执行代码中的调用仍在缓冲中。
  • 没错。 setvbuf 不会在 exec 中保留,这就是为什么我说你不能从父进程中做到这一点。我想我可以说得更清楚...您了解文件描述符和FILE 之间的区别吗?也许你可以读一读……
猜你喜欢
  • 2011-08-05
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
  • 2011-10-06
  • 2015-07-05
  • 1970-01-01
相关资源
最近更新 更多