如何使用 fopen() 锁定文件?
- 2024-11-14 08:29:00
- admin 原创
- 14
问题描述:
fopen
我想知道当我使用(不是)打开文件时是否有任何方法可以在 Linux 中锁定和解锁文件open
?
根据 Stack Overflow 问题C fopen vs open,fopen
更受青睐open
。
如何通过创建和删除锁文件来实现我自己的文件锁(如果可能)?
解决方案 1:
我强烈反对fopen
优于 的说法。由于符号链接漏洞/竞争条件,在可由其他用户写入的目录中写入文件时open
无法安全使用,因为没有选项。如果您需要在 POSIX 系统上使用 stdio,最好使用和 ,而不是直接调用。fopen
`O_EXCLopen
fdopen`fopen
现在,至于锁定,这取决于您想要做什么。POSIX 没有像 Windows 那样的强制锁定,但如果您只是想确保您正在处理新文件而不是破坏现有文件或跟踪符号链接,请根据需要使用O_EXCL
和O_NOFOLLOW
选项。如果您想在初始打开之外进行协作锁定,请使用fcntl
锁。
解决方案 2:
在 Linux 中,如果您需要文件描述符(例如,传递给文件锁定原语),则可以使用fileno(FILE*)
来检索它。检索文件描述符后,您可以像使用 一样使用它open
。
例如,
int fd = open("myfile.txt", flags);
int result = flock(fd, LOCK_SH);
你也可以这样做:
FILE* f = fopen("myfile.txt", "r");
int result = flock(fileno(f)), LOCK_SH);
请注意,这fileno
是在 POSIX 标准中定义的,但没有在 C 或 C++ 标准中定义。
至于你的第二个问题,Linuxopen()
手册页是这么说的:
使用锁文件执行原子文件锁定的解决方案是在同一文件系统上创建一个唯一文件(例如,合并主机名和 pid),使用link(2)链接到该锁文件。如果 link() 返回 0,则锁定成功。否则,对唯一文件使用stat(2)检查其链接数是否已增加到 2,在这种情况下锁定也成功。
解决方案 3:
可以使用 锁定文件flock()
。其语法是
#include <sys/file.h>
#define LOCK_SH 1 /* shared lock */
#define LOCK_EX 2 /* exclusive lock */
#define LOCK_NB 4 /* don't block when locking */
#define LOCK_UN 8 /* unlock */
int flock(int fd, int operation);
fopen()
第一个文件使用或打开。然后使用以下方法open()
锁定此打开的文件flock()
int fd = open("test.txt","r");
int lock = flock(fd, LOCK_SH); // Lock the file . . .
// . . . .
// Locked file in use
// . . . .
int release = flock(fd, LOCK_UN); // Unlock the file . . .
解决方案 4:
fopen
请注意,如果锁文件/var/lock/my.lock
不存在,下面的代码将失败(并返回 NULL)。
FILE* f = fopen("/var/lock/my.lock", "r");
int result = flock(fileno(f)), LOCK_SH);
如果锁文件不存在则需要创建它,请使用fopen
with 。w+
FILE* f = fopen("/var/lock/my.lock", "w+");
int result = flock(fileno(f)), LOCK_SH);
解决方案 5:
如果您希望简单地实现自己的锁,我建议您使用 Rob 的答案使用 flock。如果您希望以复杂的方式实现它,例如为了实现高可用性,您可以尝试使用线程定期触摸文件之类的方法。所有其他想要锁定文件的程序也应该检查文件以查看其更新时间是否已在另一个固定但更大的间隔内更新(较大的部分很重要)。对于大多数应用程序来说,这可能有点过头了,但它处理崩溃、冻结等问题比 flock 好得多。
解决方案 6:
还有另一种使用open()函数的方法,但我不确定这个称为锁定文件的方法。我正在使用文件权限来打开文件。
代码在这里:
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#define FILE_NAME "hello.txt"
int main()
{
int fd;
fd = open(FILE_NAME, O_CREAT, S_IRWXU);
// Error checking
if(fd == -1){
perror("[error]
");
}
else{
printf("[file is opened]
");
}
return 0;
}
我使用了一个权限标志(第三个参数)。此标志为用户提供读取、写入和执行权限。
$ls -alh
total 24K
drwxrwxr-x 2 arien arien 4.0K Dec 28 20:56 .
drwxrwxr-x 18 arien arien 4.0K Dec 27 22:20 ..
-rwxrwxr-x 1 arien arien 8.5K Dec 28 20:56 fopen
-rw-rw-r-- 1 arien arien 290 Dec 28 20:56 fopen.c
-rwx------ 1 arien arien 0 Dec 28 20:55 hello.txt
man [function_name]
小提示:如果你使用的是 Ubuntu 或 Debian,你可以使用open() 函数的手册页查看函数描述。
解决方案 7:
下面的代码不允许我使用 lockf 锁定文件,但 flock 可以正常工作
#include <iostream>
#include <unistd.h>
#include<thread>
#include <vector>
#include <sys/file.h>
#include <fcntl.h>
#include <string.h>
using namespace std;
void append()
{
FILE *fp=fopen("a.txt","a");
if(fp)
{
cout<<lockf(fileno(fp),F_LOCK,0)<<endl;
//flock(fileno(fp), LOCK_EX);
fprintf(fp,"abcdefghijklmnopqrstuvwxyz
");fflush(fp);
sleep(1);
fprintf(fp,"^$^&%&*&^&*(*)_*)_()_*&***&(
");fflush(fp);
fclose(fp);
}
else {
printf("null
");
}
}
int main()
{
fclose(fopen("a.txt","w"));
//return 0;
vector<thread*> v;
//#pragma omp parallel for
for(int i=0;i<1000;++i)
{
v.push_back(new thread(append));
//append();
}
for(auto y:v)
{
y->join();
delete y;
}
return 0;
}
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件