繁体   English   中英

无法获取文件锁定

[英]can't acquire a lock on a file

FileLocker_wo.h

#include <string>

namespace Utils
{
        namespace FileLocker
        {
                bool lock_file(std::string aFileName, int& aFileDescriptor);

                bool unlock_file(int& aFileDescriptor);

                bool is_file_locked(std::string aFileName);
        };
}

FileLocker_wo.cpp

namespace Utils
{
        namespace FileLocker
        {
                bool lock_file(std::string aFileName, int& aFileDescriptor)
                {
                        aFileDescriptor = open(aFileName.c_str(), O_RDWR);

                        if (aFileDescriptor != -1)
                        {
                                if (lockf(aFileDescriptor, F_TLOCK, 0) == 0)
                                {
                                        return true;
                                }

                                std::cout << strerror(errno) << std::endl;
                        }

                        return false;
                }

                bool unlock_file(int& aFileDescriptor)
                {
                        if (lockf(aFileDescriptor, F_ULOCK, 0) == 0)
                        {
                                std::cout << "unloced file" <<  std::endl;
                                close(aFileDescriptor);
                                return true;
                        }
                        close(aFileDescriptor);
                        return false;
                }

                bool is_file_locked(std::string aFileName)
                {
                        int file_descriptor = open(aFileName.c_str(), O_RDWR);

                        if (file_descriptor != -1)
                        {
                                int ret = lockf(file_descriptor, F_TEST, 0);

                                if (ret == -1  && (errno == EACCES || errno == EAGAIN))
                                {
                                        std::cout << "locked by another process" << std::endl;
                                        close(file_descriptor);
                                        return true;
                                }

                                if (ret != 0)
                                {
                                    std::cout << "return value is " << ret << " " << strerror(errno) << std::endl;
                                }

                        }
                        close(file_descriptor);
                        return false;
                }
        }
}

p1.cpp

#include <iostream>
#include <fstream>

#include "FileLocker_wo.h"


int main()
{

        int fd = -1;
        if (Utils::FileLocker::lock_file("hello.txt", fd))
        {
                std::ofstream out("hello.txt");
                out << "hello ding dong" << std::endl;
                out.close();

                std::cout << "locked" << std::endl;
                sleep(5);
                if (Utils::FileLocker::unlock_file(fd))
                {
                        std::cout << "unlocked" << std::endl;
                }
        }

        return 0;
}

p2.cpp

#include "FileLocker_wo.h"
#include <iostream>
#include <fstream>

int main()
{
        int max_trys = 2;
        int trys = 0;
        bool is_locked = false;

        do
        {
                is_locked = Utils::FileLocker::is_file_locked("hello.txt");

                if (!is_locked)
                {
                        std::cout << "not locked" << std::endl;
                        break;
                }

                std::cout << "locked" << std::endl;

                sleep(1);
                ++trys;
        }
        while(trys < max_trys);

        if (!is_locked)
        {
                std::string s;
                std::ifstream in("hello.txt");
                while(getline(in,s))
                {
                        std::cout << "s is " << s << std::endl;
                }
        }

        return 0;
}

我正在尝试在一个进程中获取文件锁,并使用lockf(p1.cpp,p2.cpp)检查在另一个进程中该文件是否有任何锁。

在p1.cpp中,我锁定了hello.txt文件并等待5秒钟。 同时,我启动p2.cpp并通过其他进程检查是否有任何锁定,但始终没有锁定>我在最近2个小时中一直停留在此状态。

谁能告诉我这是什么问题?

您已经克服了POSIX文件锁中最棘手的设计错误之一。 你可能不知道这一点,因为你只读过lockf手册页 ,而不是fcntl手册页 ,所以这里的重要位fcntl手册页:

  • 如果某个进程关闭了引用该文件的任何文件描述符,则该进程对该文件的所有锁定都将被释放,无论在哪个文件描述符上获得了锁定。

这意味着在这段代码中

    if (Utils::FileLocker::lock_file("hello.txt", fd))
    {
            std::ofstream out("hello.txt");
            out << "hello ding dong" << std::endl;
            out.close();

即使 out是与lock_file使用的操作系统级别的“打开文件描述”,您在调用out.close()也会丢失对文件的锁定!

为了安全地使用POSIX锁,您必须确保对要锁定的文件调用一次open()并且每个进程调用一次 ,不得复制文件描述符,并且仅在准备删除时才再次关闭它锁。 因为可能没有任何方法(甚至使用不可移植的扩展名)从文件描述符构造iostreams对象,或从iostreams对象提取文件描述符,所以阻力最小的途径是使用OS级I / O原语( openclosereadwritefcntllseekftruncate )包含您需要对其应用POSIX锁的文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM