创建避免争用条件的新文件

Creating a new file avoiding race conditions

提问人:Alberto M 提问时间:2/29/2016 最后编辑:CommunityAlberto M 更新时间:3/3/2016 访问量:1945

问:

我需要开发一个C++例程来执行这个看似微不足道的任务:仅在文件不存在时才创建文件,否则不执行任何操作/引发错误。

由于我需要避免竞争条件,我想使用“请求宽恕而不是许可”原则(即尝试预期的操作并检查它是否成功,而不是提前检查先决条件),据我所知,这是用于此目的的唯一健壮且可移植的方法 [维基百科文章][getline 示例]。

尽管如此,我还是找不到在我的情况下实现它的方法。我能想到的最好的办法是打开一个 in 模式(或 ing with ),用 (C++) 或 (C) 检查输出位置,如果该位置不为零,则中止。然而,这有两个缺点,即如果文件存在,它会被锁定(尽管时间很短)并且其修改日期被更改。fstreamappfopen"a"tellpftell

我检查了 for 的其他可能组合以及字符串,但没有找到适合我需求的选项。在 C 和 C++ 标准库以及 Boost 文件系统中的进一步搜索被证明是徒劳的。ios_base::openmodefstreammodefopen

有人可以指出一种方法,在不依赖特定于操作系统的功能的情况下以稳健的方式(没有附带影响,没有竞争条件)执行我的任务吗? 我的具体问题在 Windows 中,但可移植的解决方案将是首选。

编辑:BitWhistler的回答完全解决了C程序的问题。尽管如此,我还是惊讶于似乎不存在C++惯用的解决方案。要么与Andrew Henle建议的属性一起使用,但是该属性是特定于操作系统的(在Windows中,该属性似乎使用附加下划线[MSDN]调用),或者单独编译C11文件并将其与C++代码链接。此外,获得的文件描述符不能转换为流,除非使用非标准扩展名(例如 GCC 的 )。我希望C++的未来版本将实现子属性,并可能实现文件流的相应修饰符。openO_EXCL_O_EXCL__gnu_cxx::stdio_filebuf"x"ios::

C++ C IOstream 标准

评论

0赞 user2807083 2/29/2016
是否要避免多个线程或多个进程之间的争用条件?
3赞 Andrew Henle 2/29/2016
你的操作系统是什么?POSIX 提供 open( filename, O_CREAT |O_EXCL ... )去做你想做的事情。
1赞 Kirill Kobelev 2/29/2016
Win32 API 允许这样做。我肯定知道这一点。
2赞 Martin James 2/29/2016
我从不做你似乎建议的事情。如果多个线程需要写入一个文件,我会将输出排入一个线程,该线程管理执行所有输出的文件。文件系统上的竞争消失了,调试变得更加容易,管理输出文件(例如限制其大小,每天选择一个新文件)变得微不足道。
0赞 Alberto M 2/29/2016
很抱歉没有澄清:这里可能的竞争条件是我无法控制的外部过程。我完全同意应用程序中的 I/O 应该由单个线程执行。

答:

3赞 yb303 2/29/2016 #1

新的C标准(C2011,不是C++的一部分)增加了一个新的标准子说明符(“x”),可以附加到任何“w”说明符(形成“wx”,“wbx”,“w+x”或“w+bx”/“wb+x”)。如果文件存在,此子说明符会强制函数失败,而不是覆盖它。

来源: http://www.cplusplus.com/reference/cstdio/fopen/