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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 06:22:51  来源:igfitidea点击:

How do I lock files using fopen()?

clinux

提问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, fopenis preferred over open.

基于堆栈溢出问题C fopen vs openfopen优于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 filenois 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 fopenis prefered over open. It's impossible to use fopensafely when writing a file in a directory that's writable by other users due to symlink vulnerabilities/race conditions, since there is no O_EXCLoption. If you need to use stdio on POSIX systems, it's best to use openand fdopenrather than calling fopendirectly.

我强烈不同意fopenopen. fopen由于符号链接漏洞/竞争条件,在其他用户可写的目录中写入文件时,不可能安全使用,因为没有O_EXCL选项。如果需要在 POSIX 系统上使用 stdio,最好使用openandfdopen而不是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_EXCLand O_NOFOLLOWoptions, as appropriate. If you want to do cooperative locking beyond the initial open, use fcntllocks.

现在,至于锁定它取决于您想要做什么。POSIX 没有像 Windows 那样的强制锁定,但如果您只是想确保您正在使用新文件而不是破坏现有文件或遵循符号链接,请根据需要使用O_EXCLO_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 fopenwill fail (and return NULL) if the lock file /var/lock/my.lockdoesn't exist.

请注意,fopen如果锁定文件/var/lock/my.lock不存在,下面的代码将失败(并返回 NULL)。

FILE* f = fopen("/var/lock/my.lock", "r");
int result = flock(fileno(f)), LOCK_SH);

Use fopenwith w+if you need the lockfile to be created if it doesn't exist.

如果您需要创建不存在的锁文件,请使用fopenwith 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;
}