【问题标题】:File I/O across processes in Linux?Linux 中跨进程的文件 I/O?
【发布时间】:2011-02-14 20:32:15
【问题描述】:

所以,我有一个 Linux 进程,我试图在其中管理磁带上的一些文件。我有以下代码尝试从磁带上的当前存档中提取文件 catalog.xml 并将其复制到固定位置(最终,我将解析该文件并对结果进行一些处理)。但是,我的代码间歇性地无法正常工作。 tar 命令总是成功,(如果我检查文件系统,我会看到 catalog.xml 文件),但有时我的后续检查以查看文件是否存在会返回 false。我在做一些明显错误的事情吗?似乎我可能在 fork()ed 进程返回和该进程的结果在文件系统上可见之间遇到了竞争条件 - 我需要进行一些调用吗?

  pid_t tPid = vfork();
  if (0 == tPid)
  {
    int tChildRet;
    tChildRet = execlp("tar", "tar", "-xvf", "/dev/nst0", "-C", "/tmp", "catalog.xml", (char *) 0);
    _exit(-1 == tChildRet ? EXIT_FAILURE : EXIT_SUCCESS);
  }
  else
  {
    wait(&ret);
  }
std::ifstream tCatalogFile("/tmp/catalog.xml");
if (tCatalogFile)
{
   cout << "File exists!" << endl;
} else {
   cout << "File does not exist!" << endl;
}

我得到“文件存在!”或“文件不存在!”,似乎是随机的。

其他说明: 关于失败案例:

  • 如果我执行 stat ("/tmp/catalog.xml"),我会得到 -1 的返回值,并将 errno 设置为 ENOENT。
  • tar 命令(使用 -v 标志运行)产生预期的一行输出(“catalog.xml”)

/tmp 是本地 tmpfs 文件系统;磁带机是本地设备。 我在 x86_64 机器上使用 2.6.30.9 Linux 内核和 g++ 4.1.2。

提前致谢!

【问题讨论】:

  • 还有其他可能导致打开失败的错误(都取决于正在使用的文件系统)。关于文件系统的更多细节会很好。
  • 注意:如果 execlp 工作,那么它将永远不会返回。所以 _exit() 只有在 execlp() 失败时才会被调用。你也没有检查 vfork() 是否真的有效。

标签: c++ file-io filesystems fork-join


【解决方案1】:

尝试在父级调用wait 之后调用sync

如果这不起作用,您可能需要循环和/或休眠,直到父母可以打开文件,因为您知道它在那里。

【讨论】:

  • 到目前为止,这似乎工作 - 谢谢!一旦我有机会进行更彻底的测试,我会回来报告。
  • 另一个答案原来是根本原因 - 但同步调用确实解决了我在其他地方遇到的相关问题。再次感谢!
【解决方案2】:

如果execlp 成功,它永远不会到达您调用_exit 的那一行。您没有检查来自 wait 的返回值 (ret)。目前尚不清楚您为什么应该使用vfork。等等。

既然父母除了等待孩子完成之外没有做任何其他事情,为什么不让你的生活更轻松,只使用system()

【讨论】:

  • _exit是处理execlp失败的情况。我对系统也有同样的想法,因为参数是静态的,甚至不需要引用。
  • 上面的代码有些简化——在我的实际代码库中有更多的错误检查等。我没有使用 system() 因为我的程序运行的是 setuid (因此 system() 是不安全的。)
  • 我也建议waitpid 而不是wait;如果您在代码运行时有另一个子进程退出,wait 将返回其 pid 而不是您刚刚生成的子进程。总而言之,我必须同意 Emery - 为什么不使用 system,因为您在等待子进程完成时真的没有做任何其他事情?
  • Will - 我认为 waitpid vs wait 实际上是我的答案。我使用单独的线程一次在多个磁带驱动器上做同样的事情,每当我正在查看的驱动器第二次完成其 tar 命令时,故障似乎就会发生。谢谢!
  • 接受了这个答案,因为等待的返回值实际上会导致我遇到问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
  • 2017-02-27
  • 2012-08-06
  • 1970-01-01
相关资源
最近更新 更多