【问题标题】:Writing to file and mkdir race conditions C写入文件和 mkdir 竞争条件 C
【发布时间】:2013-02-13 23:39:05
【问题描述】:

我做了一个函数,试图创建一个目录,然后写一个简单的文件:

buffer = "Hello world!";
string url = "a/b/c/d/";
string tmp = "";
string done = "";
while((tmp = GetBaseDir(url)).compare("")!=0){
    done+=tmp;
    mkdir(done.c_str(), 0777);
} // GetBaseDir returns "a/", and changes url to "b/c/d/"
ofstream file;
file.open((url+"file.txt").c_str(),ios::trunc);
file << buffer;
file.close();

如您所见,它只会尝试,如果出现故障,它会继续进行。

我读到如果另一个进程以写权限打开同一个文件,“打开”将失败。但是,这是真的吗?
如果我同时运行此代码的多个实例,mkdir 和写入操作会发生什么情况?

【问题讨论】:

  • 编辑:我没有尝试重现这种竞争条件。我想知道 mkdir 是否可靠地执行,或者我必须使用互斥锁来保护它。以及c++中的写操作。当我搜索这个问题时,我没有找到相关的东西,而是找到了更多关于如何使用 mkdir linux.die.net/man/3/mkdir 的问题或信息,而不是它是如何工作的。文档页面没有提到竞争条件。我在具有竞争条件的写操作中发现的也没有帮助。他们用不同的例子提到了竞争条件,但我已经知道了。
  • 我发现我可以通过使用带有选项 O_WRONLY | 的 open 来保护文件。 O_CREAT | O_EXCL。但同样,我不确定这是否足够,或者我必须使用互斥锁来确保它正常工作。
  • 当您使用 O_EXCL 时,将自动创建文件,并且任何其他同时的、独占的打开调用都会失败。它本身基本上就是一个互斥体。
  • 谢谢,你知道mkdir吗?我的假设是它是可靠的,因为它在 linux API 中。虽然,我不太确定。

标签: c++ linux race-condition mkdir


【解决方案1】:

当目录已经存在时,手册页说明 mkdir 失败。它返回 -1 而不是 0。如果你忽略它,你的代码通常可以正常工作,只要 a/b/c/d 实际上是目录。竞争过程可能会将它们创建为其他东西,从而导致错误。不清楚为什么要使用模式 0777,因为将 0700 甚至 0770 与特殊组一起使用会好得多。如果您确定它们将始终是目录,那么代码的每个实例都将确保 dir 路径存在,并且唯一的争用将是创建文件。

NAME
   mkdir -- make a directory file
SYNOPSIS
   #include <sys/stat.h>
   int mkdir(const char *path, mode_t mode);
RETURN VALUES
   A 0 return value indicates success.  A -1 return value indicates an
   error, and an error code is stored in errno.
ERRORS
     Mkdir() will fail and no directory will be created if:
   ...
   [EEXIST]           The named file exists.

【讨论】:

    猜你喜欢
    • 2021-06-03
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 2020-07-12
    相关资源
    最近更新 更多