【问题标题】:Delay required between a file created via external program using system() and opening it via open()?使用 system() 通过外部程序创建的文件和通过 open() 打开文件之间需要延迟吗?
【发布时间】:2012-01-23 21:09:16
【问题描述】:

我正在尝试从我的程序创建一个 TAR 存档,然后打开存档以进行进一步处理。我在调用 system()open() 之间有 2 秒的延迟。到目前为止,它工作正常,但我不确定为什么需要 2 秒延迟或者它是否是正确的解决方案。

没有延迟,我从open() 调用中得到错误代码2(ENOENT“没有这样的文件或目录”)。我的第一个想法是文件系统更新速度不够快,open() 找不到文件。但是如果系统真的很忙呢?我需要更长的延迟吗?我应该循环直到open() 成功而不是延迟?问题是完全不同的吗?

更新
根文件系统是 EXT2。 /tmp 使用 TMPFS 安装在 RAM 中。我正在使用tar创建一个存档,而不是提取其中的内容。本质上,我的程序应该创建一些日志文件的存档并通过网络发送它们(这就是我在创建存档后打开存档的原因)。

int return_value = system("/bin/tar -czf /tmp/logs.tar.gz /var/log/mylogs.log* &> /dev/null");
// error checks on return_value as described here: http://linux.die.net/man/2/wait
if(return_value != 0) {
  return return_value;
}
//usleep(2000000);
return_value = open("/tmp/logs.tar.gz", O_RDONLY | O_LARGEFILE, 0);
// success or failure depending on whether there's a delay or not

【问题讨论】:

  • 如果你使用popen会发生什么?
  • 没错,这是popen() 的工作。教system()的教程应该被砍了。
  • popen()system() 具有相同的最终结果。 IE。 open() 调用以同样的方式失败,没有延迟。
  • 我们在这里讨论的是什么文件系统?是否涉及网络传输?您可能是蹩脚的消费级 NAS 设备的受害者吗? (去过那里,看到...例如,NAS 开发人员使用 CIFS 导出其文件 - 并且从不存储文件戳,这意味着 rsync 无法正常工作。)
  • 也许问题出在其他地方。您应该展示实际代码以获得真正的帮助。

标签: c linux file race-condition ext2


【解决方案1】:

您甚至可以通过在程序中直接使用libtar 来避免运行外部tar 命令。


添加

你应该向我们展示你的程序。我很确定如果对system 的调用只是通过tar 提取了一些文件,则它在成功 system 调用之后可用,例如类似:

 int err = system("/bin/tar xf /tmp/foo.tar bar");
 int fd = -1;
 if (err == 0)
      fd = open("bar", O_RDONLY);
 // fd is available

在这段代码中没有理由等待几秒钟。你可能在做更复杂的事情,或者你忘了测试system的结果

【讨论】:

  • 未安装在我的系统上,tar 已安装,使用起来更简单。此外,执行的其他外部程序可能会受益。
  • 我添加了一个system 的示例,它应该可以工作。
【解决方案2】:

您认为您正在使用“&>”重定向 tar 的输出,但实际上您是在后台运行它,因为 system() 恰好调用了一个不支持 &> 的 shell,因此将其解释为“&”后跟“>”。延迟会导致您的程序等待足够长的时间以使 tar 完成。

修复方法是修改您的命令以使用您的 shell 支持的语法。从 tar 抛出错误输出在任何情况下都可能是一个错误。

【讨论】:

    【解决方案3】:

    这是我会尝试的:

    1. fork/exec tar 你自己,并让你的父母收集 tar-child。如果系统在文件系统中引入竞争条件,控制子进程的创建/获取可能会有所帮助。

    2. touch 一个空文件(fopen 用于写入,close)然后tar 进入新文件。

    3. tar--verify选项;该文件必须存在才能被验证:)

    【讨论】:

    • 是的,但是如果我们在假设某处存在错误的情况下进行操作,这将排除它是代码/库问题的可能性,让我们专注于其他事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    • 2018-02-15
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    • 2011-06-28
    相关资源
    最近更新 更多