【问题标题】:What "gotchas" should I be aware of when writing to the same file descriptor in a parent and child process?在父进程和子进程中写入相同的文件描述符时,我应该注意什么“陷阱”?
【发布时间】:2022-09-27 09:23:33
【问题描述】:

背景:我在 Linux 上使用 C(和非常 C-ish C++)。父进程有一个打开的文件描述符(编辑:不是文件描述符,实际上是一个FILE 指针),它以“分段”格式写入数据。子进程将它用于同样的目的。只要子进程正在运行,就可以保证父进程不会尝试将更多数据写入其FILE 指针的副本。子进程退出,父进程等待它,然后它将更多数据写入文件。

出现正常工作,但我仍然怀疑它。我需要在父项中重新寻找到底吗?我需要处理任何同步问题吗?

  • 没有minimal reproducible example,就不可能有权威的答案。唯一可以权威说明的是,如果文件以附加模式打开,则不需要显式查找。
  • 您说“文件描述符”,但这是一个 POSIX 概念。 C 只有FILE 指针。 (C也没有父母和孩子)。但是,如果没有实际代码,则不清楚您在说什么。
  • 对不起这是我的错。是的,它是一个FILE 指针。

标签: c++ c linux


【解决方案1】:

文件描述符通常来自 Unix,特别是 Linux,并且很多行为都是由 POSIX 标准化的。您说父进程和子进程共享相同的文件描述符。那是不可能的;文件描述符特定于一个进程。

假设父打开一个文件(假设文件描述符为3),因此还有一个新的打开文件描述;然后父进程分叉。在 fork 之后,每个进程都有一个单独的文件描述符(但它们都使用文件描述符 3),但它们共享相同的打开文件描述。是的:“打开文件描述符”和“打开文件描述”是不同的!每个打开的文件描述符都有一个打开的文件描述,但是一个打开的文件描述可以与许多打开的文件描述符相关联,并且这些描述符不必都与同一个进程相关联。

打开文件描述中的关键数据位之一是当前位置(对于读取或写入 - 在这里重要的是写入)。 因此,当孩子写字时,父母和孩子的当前位置都会移动。因此,无论何时父母写,它都会在孩子写完的位置之后写。

你所看到的是有保证的。至少在父级打开文件和分叉的情况下。

请注意,在所讨论的场景中,O_APPEND 标志不是必需的或相关的。但是,如果您担心它,您可以使用O_APPEND 标志打开文件,然后每次正常写入(不是通过pwrite() 写入)都会将数据写入文件的当前末尾。即使两个进程不共享相同的打开文件描述,这也将起作用。

POSIX 规范:

【讨论】:

    【解决方案2】:

    如果您在谈论 POSIX 文件描述符,那么对文件描述符的每个 write 调用都是原子的,并且独立于其他进程可能对引用同一对象的文件描述符执行的操作影响底层内核资源对象。如果两个进程几乎同时执行write,则操作将由内核排序,其中一个完全发生(尽管它可能写入的数据少于请求的数据),然后另一个发生。

    在您的情况下,听起来您正在同步,这样您就知道所有父级写入都发生在子级开始之前(fork 之前)或完成之后(wait 之后),这保证了@987654325 的顺序@电话。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多