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

在C中读取文件时,如何防止任何其他进程写入文件? 背景,c,multithreading,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);

在我的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);
}
FILE*FILE=fopen(“config.txt”、“r”);
如果(文件)
{
字符*行;
尺寸与长度;
尺寸不可读取;
int test_case_number=0;
while((read=getline(&line,&length,file))!=-1)
{
printf(“%s”,第行);
}
}
其他的
{
fputs(“提供的文件不存在。\n\n”);
出口(1);
}
问题 但是,在读取此文件时,我希望防止任何其他进程在读取时写入
config.txt
。我如何才能做到这一点?

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

在打开的文件上应用或删除建议锁定

锁\u EX放置一个独占锁。只有一个进程可以保存一个进程 在给定时间对给定文件的独占锁定

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

用抽象例子提问:或者检查这个

重要提示:@JonathanLeffler评论道“注意术语“顾问锁”-这意味着如果写入过程没有测试锁,它将能够写入。在类似POSIX的系统上,您可以使用
flock()
lockf()
fcntl()
通过
fileno(fp)
锁定文件描述符。”.

如果您必须“防御”您自己的流程或“行为良好”的流程,那么您需要使用
flock

   fp = fopen(fileName, fileMode);
   if (fp != NULL) {
       flock(fileno(fp), LOCK_EX);
       ...
       fclose(fp); fp = NULL;
   }
但是这些锁只是建议性的,也就是说,任何其他进程都可以选择忽略它们。或者不用费心检查。我刚刚尝试创建一个文件,打开它并用LOCK_EX锁定,然后休眠60秒。在此期间,另一个进程可以自由地对文件执行任何操作(Linux,Ubuntu 18.04-LTS)

但是如果您需要强制锁定,这并不是所有平台都可以使用的,因为内核必须配合。您将看到关于如何使用Linux中有限的强制锁支持的描述和示例

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

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


解决方法可以是临时将正在处理的文件重命名为唯一的名称,可能会创建一个空文件,用旧名称替换,然后在完成后重新命名;或者如上所述复制文件,留下一份副本供其他程序读取。也可以通过更改文件权限来实现写拒绝。这些解决方案需要处理一些边缘情况,例如进程崩溃或机器挂起,然后再恢复原状。

查看
flock()
@LSerni的手册页,但我不确定
flock()
是否能与
fopen()
一起使用,然后您想要强制文件锁定。这取决于很多事情。您的平台是什么?标准C没有提供防止并发读写器的机制。POSIX提供了诸如和之类的自愿机制,但是如果编写过程没有测试锁,那么阅读器就无能为力。有些系统在文件上使用特殊的
chmod()
模式提供强制锁定,但许多系统没有。@LSerni Ubuntu linux请注意术语“顾问锁”-这意味着如果写入过程没有测试锁,它将能够写入。在类似POSIX的系统上,可以使用
flock()
lockf()
fcntl()
通过
fileno(fp)
锁定文件描述符。如果我
open()
然后
flock()
,我将如何实现我没有
getLine()的读取功能
?@NicholasAdamou:如果你使用文件描述符(
open()
),那么你就可以使用
read()
write()
作为你的主要I/O接口(最后是
close()
),尽管对于各种特殊的I/O目的有很多替代方法。@NicholasAdamou这是最简单的部分,有很多这样做的例子。注意乔纳森在第一次评论中提到的,这非常重要。