C语言 用 O_CREAT 打开 - 它是打开的还是创建的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15798450/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
open with O_CREAT - was it opened or created?
提问by Sergey
I have 10 processes which try open the same file more or less at the same time using open(O_CREAT) call, then delete it. Is there any robust way to find out which process actually did create the file and which did open already create file, for instance, if I want to accurately count how many times that file was opened in such scenario.
我有 10 个进程尝试使用 open(O_CREAT) 调用或多或少地同时打开同一个文件,然后将其删除。是否有任何可靠的方法来找出哪个进程确实创建了文件,哪个进程打开了已经创建的文件,例如,如果我想准确地计算在这种情况下打开该文件的次数。
I guess I could put a global mutex on file open operation, and do a sequence of open() calls using O_CREAT and O_EXCL flags, but that doesn't fit my definition of "robust".
我想我可以在文件打开操作上放置一个全局互斥锁,并使用 O_CREAT 和 O_EXCL 标志执行一系列 open() 调用,但这不符合我对“稳健”的定义。
采纳答案by jxh
Based roughly on your comments, you want something along the lines of this function:
粗略地根据你的评论,你想要一些类似这个函数的东西:
/* return the fd or negative on error (check errno);
how is 1 if created, or 0 if opened */
int create_or_open (const char *path, int create_flags, int open_flags,
int *how) {
int fd;
create_flags |= (O_CREAT|O_EXCL);
open_flags &= ~(O_CREAT|O_EXCL);
for (;;) {
*how = 1;
fd = open(path, create_flags);
if (fd >= 0) break;
if (errno != EEXIST) break;
*how = 0;
fd = open(path, open_flags);
if (fd >= 0) break;
if (errno != ENOENT) break;
}
return fd;
}
This solution is not bullet proof. There may be cases (symbolic links maybe?) that would cause it to loop forever. Also, it may live-lock in certain concurrency scenarios. I'll leave resolving such issues as an exercise. :-)
此解决方案不是防弹的。可能有些情况(符号链接可能?)会导致它永远循环。此外,它可能会在某些并发场景中实时锁定。我将解决此类问题作为练习。:-)
In your edited question, you pose:
在您编辑的问题中,您提出:
I have 10 processes which try open the same file more or less at the same time using open(O_CREAT) call, then delete it.
我有 10 个进程尝试使用 open(O_CREAT) 调用或多或少地同时打开同一个文件,然后将其删除。
A hack-ish, but more bullet proof, solution would be to give each process a different user ID. Then, just use the regular open(path, O_CREAT|...)call. You can then query the file with fstat()on the file descriptor, and check the st_uidfield of the statstructure. If the field equals the processes' user ID, then it was the creator. Otherwise, it was an opener. This works since each process deletes the file after opening.
一个hack-ish但更防弹的解决方案是给每个进程一个不同的用户ID。然后,只需使用常规open(path, O_CREAT|...)调用。然后您可以使用文件描述符查询文件fstat(),并检查结构的st_uid字段stat。如果该字段等于进程的用户 ID,那么它就是创建者。否则,这是一个开场白。这是有效的,因为每个进程在打开后都会删除文件。
回答by suspectus
Use O_EXCLflag with O_CREAT. This will fail if the file exists and errno will be set to EEXIST. If it does fail
then attempt open again without O_CREATand without O_EXCLmodes.
将O_EXCL标志与O_CREAT. 如果文件存在并且 errno 将设置为EEXIST. 如果它确实失败,则尝试在O_CREAT无O_EXCL模式和无模式下再次打开。
e.g.
例如
int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0644);
if ((fd == -1) && (EEXIST == errno))
{
/* open the existing file with write flag */
fd = open(path, O_WRONLY);
}

