[英]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原語( open
, close
, read
, write
, fcntl
, lseek
, ftruncate
)包含您需要對其應用POSIX鎖的文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.