Linux 如何使用 fopen() 锁定文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7573282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I lock files using fopen()?
提问by Amir
I wonder if there is any way to lock and unlock a file in Linux when I open a file using fopen
(not open
)?
我想知道当我使用fopen
(not open
)打开文件时,是否有任何方法可以在 Linux 中锁定和解锁文件?
Based on Stack Overflow question C fopen vs open, fopen
is preferred over open
.
基于堆栈溢出问题C fopen vs open,fopen
优于open
.
How can I implement my own file lock (if possible) by creating and deleting lock files?
如何通过创建和删除锁定文件来实现我自己的文件锁定(如果可能)?
回答by Rob?
In Linux, if you need a file descriptor (e.g., to pass to a file-locking primitive), you can use fileno(FILE*)
to retrieve it. After retrieving the file descriptor, you can use it as if it had been returned by open
.
在 Linux 中,如果您需要一个文件描述符(例如,传递给文件锁定原语),您可以使用fileno(FILE*)
它来检索它。检索文件描述符后,您可以像使用open
.
For example, instead of
例如,代替
int fd = open("myfile.txt", flags);
int result = flock(fd, LOCK_SH);
you could equally well do this:
你同样可以做到这一点:
FILE* f = fopen("myfile.txt", "r");
int result = flock(fileno(f)), LOCK_SH);
Note that fileno
is defined in the POSIX standard, but not in C or C++ standards.
请注意,它fileno
是在 POSIX 标准中定义的,而不是在 C 或 C++ 标准中定义的。
As for your second question, the Linux open()
man pagehas this to say:
至于你的第二个问题,Linuxopen()
手册页是这样说的:
The solution for performing atomic file locking using a lockfile is to create a unique file on the same file system (e.g., incorporating hostname and pid), use link(2)to make a link to the lockfile. If link() returns 0, the lock is successful. Otherwise, use stat(2)on the unique file to check if its link count has increased to 2, in which case the lock is also successful.
使用 lockfile 执行原子文件锁定的解决方案是在同一文件系统上创建一个唯一的文件(例如,合并主机名和 pid),使用link(2)建立到 lockfile 的链接。如果 link() 返回 0,则锁定成功。否则,在唯一文件上使用stat(2)来检查它的链接数是否增加到 2,在这种情况下锁定也成功。
回答by dbeer
If you wish to implement your own lock simply, I suggest Rob's answer of using flock. If you wish to implement it in a complex manner, such as for high availability, you can try something like using a thread to touch a file at a regular interval. All other programs wanting to lock the file should also check the file to see if its update time has been updated in at another fixed, but larger interval (the larger part is important). This is probably overkill for most applications, but it handles things such as crashes, freezes, etc. much better than flock.
如果您希望简单地实现自己的锁,我建议 Rob 使用 flock 的答案。如果您希望以复杂的方式实现它,例如为了高可用性,您可以尝试使用线程定期访问文件之类的方法。所有其他想要锁定文件的程序也应该检查文件以查看它的更新时间是否已在另一个固定但更大的时间间隔内更新(较大的部分很重要)。对于大多数应用程序来说,这可能有点矫枉过正,但它比 flock 处理崩溃、冻结等问题要好得多。
回答by R.. GitHub STOP HELPING ICE
I would strongly disagree with the claim that fopen
is prefered over open
. It's impossible to use fopen
safely when writing a file in a directory that's writable by other users due to symlink vulnerabilities/race conditions, since there is no O_EXCL
option. If you need to use stdio on POSIX systems, it's best to use open
and fdopen
rather than calling fopen
directly.
我强烈不同意fopen
比open
. fopen
由于符号链接漏洞/竞争条件,在其他用户可写的目录中写入文件时,不可能安全使用,因为没有O_EXCL
选项。如果需要在 POSIX 系统上使用 stdio,最好使用open
andfdopen
而不是fopen
直接调用。
Now, as for locking it depends on what you want to do. POSIX does not have mandatory locking like Windows, but if you just want to ensure you're working with a new file and not clobbering an existing file or following a symlink, use the O_EXCL
and O_NOFOLLOW
options, as appropriate. If you want to do cooperative locking beyond the initial open, use fcntl
locks.
现在,至于锁定它取决于您想要做什么。POSIX 没有像 Windows 那样的强制锁定,但如果您只是想确保您正在使用新文件而不是破坏现有文件或遵循符号链接,请根据需要使用O_EXCL
和O_NOFOLLOW
选项。如果您想在初始打开之后进行协作锁定,请使用fcntl
锁。
回答by Yogeesh H T
Files can be locked by using flock()
. Its syntax is
可以使用 锁定文件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);
First file is opened using fopen()
or open()
. Then this opened file is locked using flock()
as given below
使用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 . . .
回答by Shoaib Ahmed
Note that in below code fopen
will fail (and return NULL) if the lock file /var/lock/my.lock
doesn't exist.
请注意,fopen
如果锁定文件/var/lock/my.lock
不存在,下面的代码将失败(并返回 NULL)。
FILE* f = fopen("/var/lock/my.lock", "r");
int result = flock(fileno(f)), LOCK_SH);
Use fopen
with w+
if you need the lockfile to be created if it doesn't exist.
如果您需要创建不存在的锁文件,请使用fopen
with w+
。
FILE* f = fopen("/var/lock/my.lock", "w+");
int result = flock(fileno(f)), LOCK_SH);
回答by metarose
There is another way with open()function, but I'm not sure about this called locked file. I am using file permissions to open a file.
open()函数还有另一种方法,但我不确定这个称为锁定的文件。我正在使用文件权限打开文件。
The code is here:
代码在这里:
#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]\n");
}
else{
printf("[file is opened]\n");
}
return 0;
}
I used a flag for permissions (third argument). This flag gives read, write and execute permissions to the user.
我使用了权限标志(第三个参数)。此标志为用户提供读取、写入和执行权限。
$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
A little tip: If you are using Ubuntu or Debian, you can see the description of functions with man [function_name]
man pages of open() function.
小提示:如果您使用的是 Ubuntu 或 Debian,您可以man [function_name]
通过 open() 函数的手册页查看函数的描述。
回答by Asif Bahrainwala
The below code is not letting me lock the file using lockf, flock works fine though
下面的代码不允许我使用 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\n");fflush(fp);
sleep(1);
fprintf(fp,"^$^&%&*&^&*(*)_*)_()_*&***&(\n");fflush(fp);
fclose(fp);
}
else {
printf("null\n");
}
}
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;
}