在C中读取文件时,如何防止任何其他进程写入文件? 背景
在我的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);
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这是最简单的部分,有很多这样做的例子。注意乔纳森在第一次评论中提到的,这非常重要。