简体   繁体   English

在 C 中读取文件时,如何防止任何其他进程写入文件?

[英]How do I prevent any other process from writing to a file while reading from it in C?

Background背景

In my C program, I am reading from a file line by line.在我的 C 程序中,我正在逐行读取文件。

FILE *file = fopen("config.txt", "r");

if (file)
{
    char *line;
    size_t length;
    size_t read;
    int test_case_number = 0;

    while ((read = getline(&line, &length, file)) != -1)
    {
        printf("%s", line);
    }
}
else
{
    fputs("The provided <PATH_TO_CONFIG FILE> does not exist.\n\n");
    exit(1);
}

Issue问题

However, while I am reading this file, I want to prevent any other process from writing to config.txt while its being read.但是,在我读取此文件时,我想防止任何其他进程在读取时写入config.txt How can I do this?我怎样才能做到这一点?

In Linux, you can use flock() (focus by me):在 Linux 中,你可以使用flock() (我的重点):

Apply or remove an advisory lock on an open file.对打开的文件应用或删除咨询锁定。

LOCK_EX Place an exclusive lock . LOCK_EX放置一个排他锁 Only one process may hold an exclusive lock for a given file at a given time.在给定时间,只有一个进程可以持有给定文件的排它锁。

However, you'd need to open your file with open() , instead of fopen() .但是,您需要使用open()而不是fopen()打开文件。

Question with abstract example: flock(): removing locked file without race condition?带有抽象示例的问题: flock():在没有竞争条件的情况下删除锁定的文件? Or check this example .或者检查这个 例子

IMPORTANT: As @JonathanLeffler commented "Note the term "advisory lock" — that means that if the writing process does not test for the lock, it will be able to write. On POSIX-like systems, you can use flock() or lockf() or fcntl() locking on the file descriptor via fileno(fp) ".重要提示:正如@JonathanLeffler 评论的“注意术语“建议锁”——这意味着如果写入过程不测试锁,它将能够写入。在类似 POSIX 的系统上,您可以使用flock()lockf()fcntl()通过fileno(fp)锁定文件描述符“。

If you have to "defend" against your own processes or "well behaved" processes, then you want to use flock :如果您必须“防御”自己的流程或“表现良好”的流程,那么您需要使用flock

   fp = fopen(fileName, fileMode);
   if (fp != NULL) {
       flock(fileno(fp), LOCK_EX);
       ...
       fclose(fp); fp = NULL;
   }

But those locks are advisory only, that is, any other process can choose to ignore them .但是这些锁只是建议性的,也就是说,任何其他进程都可以选择忽略它们 Or not bother checking.或者懒得检查。 I've just tried creating a file, opening it and locking with LOCK_EX, then sleeping for 60 seconds.我刚刚尝试创建一个文件,打开它并用 LOCK_EX 锁定,然后休眠 60 秒。 During that time, another process was free to do whatever it wanted to the file (Linux, Ubuntu 18.04-LTS).在那段时间里,另一个进程可以自由地对文件做任何它想做的事情(Linux、Ubuntu 18.04-LTS)。

But if you need mandatory locking, that's not something that is available on all platforms since the kernel has to cooperate.但是,如果您需要强制锁定,这并不是在所有平台上都可用的,因为内核必须合作。 Here you will find a description and example on how the limited mandatory lock support in Linux can be used.您将在此处找到有关如何使用 Linux 中有限的强制锁支持的描述和示例。

On the other hand, in Windows this is automatic:另一方面,在 Windows 中这是自动的:

Windows defaults to automatic, mandatory file locking. Windows 默认为自动强制文件锁定。 UNIXes default to manual, cooperative file locking. UNIX 缺省为手动协作文件锁定。 In both cases, the defaults can be overridden, but in both cases they usually aren't.在这两种情况下,默认值都可以被覆盖,但在这两种情况下,它们通常都不会。 ( source ). 来源)。

A workaround can be to temporarily rename the file being worked on to a unique name, possibly creating an empty file with the old name in its place, then renaming it back once you've done;一种解决方法是暂时将正在处理的文件重命名为唯一名称,可能会创建一个使用旧名称代替的空文件,然后在完成后将其重命名; or copying the file as above, leaving a copy for other programs to read.或者如上复制文件,留一份供其他程序阅读。 Write denial can also be achieved by changing the file permissions.写入拒绝也可以通过更改文件权限来实现。 These solutions require to handle some edge cases, eg where your process crashes or the machine hangs before setting things back as they were.这些解决方案需要处理一些边缘情况,例如您的进程崩溃或机器在将事情恢复原状之前挂起的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM