【问题标题】:File read after call to system()调用 system() 后读取文件
【发布时间】:2015-04-22 03:12:31
【问题描述】:

我的 C++ 程序通过 system() 调用另一个程序。该程序写入文件。我不能修改被调用的程序。

然后我的程序需要读入写入的文件。目前,我的程序读入文件太快了,以至于其他程序的更改还没有影响到文件系统,我的程序读入了一个过时的版本。

如何强制被调用程序在我的程序尝试读取之前完成写入?或者调用程序如何检查文件是否已完成写入?

我从 fork/execv 和 CreateProcess 切换到 system(),这样程序就会阻塞,我不必等待终止。所以,如果有帮助,我可以切换回去。

现在,我唯一的想法是在调用 system() 之前删除该文件——这样除非写入完成,否则它不会存在。

任何解决方案都需要有适用于 Mac、Windows 和 Linux 的版本。

【问题讨论】:

  • 不要使用system()。这是邪恶的。
  • 您的 system() 是否直接调用您的程序?程序是否在同一个进程中完成它的任务(相对于产生一个分离的进程等)? system() 阻塞直到子进程退出;它所做的任何文件更新都应该对父级可见。
  • 我的 system() 调用确实直接调用了该程序——该程序没有做任何花哨的事情。只是一个编写简单文本文件并退出的进程。我同意任何更改都应该是可见的——这就是我使用 system() 的原因——但它不起作用。如果我稍等片刻然后打开它,我就会得到想要的行为。
  • Qix,很抱歉您认为标准 API 调用可能是邪恶的。从系统切换到 fork/exec 和 CreateProcess 是一种选择,但它不能解决这个问题。我有一个 wait() 循环来监视进程是否完成,然后读取文件。它有时有效,但有时无效。

标签: c++ file system


【解决方案1】:

你应该使用 wait() 方法来实现它。 wait 方法使父进程等待并使其休眠,直到其子进程完成。您应该使用 fork() 然后执行生成的另一个进程副本。

【讨论】:

  • fork/exec 适用于 linux 和 os x,但不适用于 windows。
  • 您可以在windows中使用系统。等待子进程完成
  • system() 在 Windows 中,是的,但不是 fork/exec。 Windows 有完全不同的进程创建模型;不是基于克隆父级。
  • 但在 windows 系统中阻塞直到子进程退出
  • fork/exec/CreateProcess vs. system() 与我的问题无关。我知道这些差异,在我的程序中的不同时间使用它们,并且在尝试 system() 之前遇到了 fork/exec 的问题。
【解决方案2】:

据我所知,如果您尝试打开文件而不是在读取模式下,而是在写入模式下,如果该文件已经被另一个进程写入,它将失败。

我建议等待一小段时间(几毫秒)以确保文件已被其他进程打开,然后尝试在其上写入,当您实际可以在文件上写入时,您就可以读取它。

我不确定 Mac 上的情况如何,但我认为它与这里的 Linux 和 Windows 相同。

最好使用forkexec 而不是系统,所以我的建议只是解决问题的一种简单方法(但不推荐用于重要项目)。

【讨论】:

  • 感谢您的建议,我将尝试添加一个等待()循环,该循环打开文件以进行写入以检测此问题...如果可行,它应该适用于 fork/exec 方法,就像以及 system() 方法。我会让你知道它是如何工作的。
  • 我认为即使使用 fork/exec 方法,操作系统也可能需要一些时间来关闭文件,因此放置等待循环仍然很有用。
  • 嗯,fopen(fname,"w") 总是成功的,程序执行得很快,并且加载了旧版本的文件。该程序使用 usleep(10000),但没有它会失败。无需循环,只需睡眠一次。我不介意每次说的等待,但感觉真的很脆弱。延迟多少才足够?当计算机速度更快时会发生什么?等
  • 您的其他程序是否锁定文件以进行写入?许多程序倾向于将文件读入内存,然后将其关闭,这样它们就不会锁定它。我认为这就是这里发生的事情。在这种情况下,您只能检查文件是否有修改,但这是特定于操作系统的。
  • 延迟是解决问题的一种方法,除非您的计算机速度非常慢(或 I/O 有问题),否则您可以使用计时器来确保安全,它不应该中断在更快的计算机上,因为睡眠时间会很长,但程序会执行得更快。
猜你喜欢
  • 2023-03-28
  • 2010-09-23
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
  • 2020-09-18
  • 1970-01-01
  • 1970-01-01
  • 2014-05-18
相关资源
最近更新 更多