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

时间:2019-12-08 17:16:04

标签: c multithreading

背景

在我的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);
}

问题

但是,当我读取此文件时,我想防止在读取过程中任何其他过程写入config.txt。我该怎么办?

2 个答案:

答案 0 :(得分:1)

在Linux中,您可以使用flock()(我关注):

  

在打开的文件上应用或删除咨询锁。

     

LOCK_EX 放置独占锁。只有一个进程可以容纳   给定文件在给定时间的排他锁。

但是,您需要使用open()而不是fopen()打开文件。

带有抽象示例的问题:flock(): removing locked file without race condition?或选中此example

重要提示:@JonathanLeffler评论说:“注意“咨询锁”一词-这意味着,如果写入过程未测试该锁,它将能够进行写入。在类似POSIX的系统上,您可以使用{{ 1}}或flock()lockf()通过fcntl()“锁定文件描述符。

答案 1 :(得分:1)

如果您必须“捍卫”自己的流程或“行为良好”的流程,那么您想使用flock

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

但是这些锁仅是 advisory ,也就是说,任何其他进程都可以选择忽略它们。还是不用费心检查。我刚刚尝试创建一个文件,将其打开并用LOCK_EX锁定,然后休眠60秒。在这段时间里,另一个过程可以自由地对文件执行任何操作(Linux,Ubuntu 18.04-LTS)。

但是如果您需要强制性锁定,则由于内核必须配合,因此并非在所有平台上都可用。 Here您将找到有关如何使用Linux中的 limited 强制性锁支持的描述和示例。

另一方面,在Windows中这是自动的:

  

Windows默认为自动强制性文件锁定。 UNIX默认为手动,   合作文件锁定。在这两种情况下,都可以覆盖默认值,但在两种情况下   通常情况并非如此。 (source)。

一种解决方法可以是暂时将正在处理的文件重命名为唯一的名称,可能会使用旧名称创建一个空文件,然后在完成后将其重命名;或按上述方式复制文件,并保留副本供其他程序读取。拒绝写入也可以通过更改文件权限来实现。这些解决方案需要处理一些边缘情况,例如在您将进程恢复原状之前,您的进程崩溃或机器挂起的位置。