当父母过早杀死孩子时,孩子会反转输出

发布于 2024-11-06 07:45:48 字数 177 浏览 1 评论 0原文

这是我想要实现的一些伪代码:

fork

子进程,dup2一个文件的输出描述符,然后

在父进程中执行不同的程序,在一段时间后杀死子

进程问题是,在我杀死之后即使子进程在某个阶段已对其进行写入,输出文件仍为空。我做错了什么?我不想等待孩子,但我也不希望它逆转已经写入文件的内容。

This is some pseudo code of what I'm trying to achieve:

fork

in the child, dup2 a output descriptor to a file then exec a different program

in parent, kill the child after a period of time

The problem is though that after I kill the child the output file is empty even though the child has written to it at some stage. What am I doing wrong? I don't want to wait for the child but I also don't want it to reverse what it's already written to file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

噩梦成真你也成魔 2024-11-13 07:45:48

如果您的孩子因信号而死亡,它不会刷新任何缓冲区,这就是您看不到任何输出的原因。有解决方案可以

  • 处理信号并刷新缓冲区
  • 使用无缓冲的 I/O(应避免这种情况)
  • 同步子级和父级(使用管道)(以便父级知道杀死子级是安全的)。

当然,第三种选择相当愚蠢:孩子向父母发出信号可以通过简单地退出来替换。

编辑
根据已编辑的问题和评论

stdio(printf、fwrite 等),出于 I/O 效率的原因使用了一些缓冲区。也就是说,当您进行简单的写入时,低级操作不会立即发生。数据被复制到某个缓冲区,然后,当库认为有必要(完整的缓冲区或其他东西)时,缓冲区将被刷新 - 将写入内容。

现在,当程序调用 exit(3)(正常进程终止)时,发生的事情之一是刷新 stdio 缓冲区。如果程序因信号而终止,stdio 缓冲区不会刷新,并且内存只是由操作系统声明。

如果你无法控制你exec的程序(假设你是一个shell),你就不能确定如果你杀死它们,它们会做他们的事情。也就是说,这不是你的责任。然而,如果您确实可以控制它们(您说了一些关于管道的事情),您可以简单地通过管道发出一些序列信号,使子级调用exit(3)

If your child dies as a result of a signal, it won't flush any buffers, that's why you don't see any output. There are solutions for this

  • Handle the signal and flush the buffers
  • Use unbuffered I/O (should avoid this)
  • Synchronize the child and the parent (using the pipe) (so that the parent knows it's safe to kill the child).

Of course, the third option is rather silly: the child signaling the parent could be replaced by simply exiting.

Edit
In light of edited question and comments

stdio (printf, fwrite etc.), for reasons of I/O efficiency uses some buffers. That is, when you do a simple write, the low-level operation doesn't happen right away. The data is copied to some buffer and later, when the library deems it necessary (full buffers or something else) the buffers will be flushed - stuff is going to be written.

Now, when a program calls exit(3) (normal process termination) on of the things that happens is that stdio buffers are flushed. If a program dies as a result of a signal, stdio buffers aren't flushed and the memory is simply claimed by the OS.

If you don't have control over the programs you exec (say you're a shell) you can't be sure they will do their thing if you kill them. That is, it's not your responsibility. If however you do have control over them (you said something about a pipe) you can simply signal through the pipe some sequence that will make the children call exit(3).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文