C++ boost::进程间::文件锁定与std::ostream一起使用时出现错误行为
我试图使用它来限制同一程序同时运行的多个实例(实现中提到的内容)。我正在C++ boost::进程间::文件锁定与std::ostream一起使用时出现错误行为,c++,linux,boost,filelock,C++,Linux,Boost,Filelock,我试图使用它来限制同一程序同时运行的多个实例(实现中提到的内容)。我正在Linux上使用1.66版本的boost 在锁定文件之前,我确保文件存在(通过使用std::ofstream和std::ios::app打开它)。我注意到一件事,如果我们关闭流,那么file\u lock将自动解锁,从而允许同一程序的多个实例同时运行 以下程序无法工作,因为文件锁定已自动释放 int main(int argc, char *argv[]) { namespace bipc = boost::inte
Linux
上使用1.66
版本的boost
在锁定文件之前,我确保文件存在(通过使用std::ofstream
和std::ios::app
打开它)。我注意到一件事,如果我们关闭流,那么file\u lock
将自动解锁,从而允许同一程序的多个实例同时运行
以下程序无法工作,因为文件锁定已自动释放
int main(int argc, char *argv[])
{
namespace bipc = boost::interprocess;
if (argc < 2)
return 0;
std::string path = argv[1];
std::string lock_path = "/var/lock/" + path + ".lock";
std::ofstream stream(lock_path, std::ios::app);
bipc::file_lock lock(lock_path.c_str());
if (!lock.try_lock())
throw std::runtime_error("Multiple instance");
std::cout << "Running" << std::endl;
stream.close();
while (true)
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}
intmain(intargc,char*argv[])
{
名称空间bipc=boost::进程间;
如果(argc<2)
返回0;
std::string path=argv[1];
std::string lock_path=“/var/lock/”+path+“.lock”;
流流的std::of(锁定路径,std::ios::app);
bipc::file_lock lock(lock_path.c_str());
如果(!lock.try_lock())
抛出std::runtime_错误(“多实例”);
std::cout我找到了原因。这是因为boost::interprocess::file_lock
是使用经典POSIX文件锁实现的
这就解释了POSIX锁的问题,因此也解释了boost文件_锁的问题
更令人不安的是,该标准规定,每当进程关闭与锁定文件对应的任何文件描述符时,进程持有的所有锁都会被丢弃,即使这些锁是使用仍然打开的文件描述符生成的。正是这个细节让大多数程序员感到惊讶,因为它要求程序格外小心,不要关闭关闭文件描述符,直到确定可以删除该文件上的锁为止
看起来我应该使用或其他使用flock
的平台库
int main(int argc, char *argv[])
{
namespace bipc = boost::interprocess;
if (argc < 2)
return 0;
std::string path = argv[1];
std::string lock_path = "/var/lock/" + path + ".lock";
std::ofstream stream(lock_path, std::ios::app);
bipc::file_lock lock(lock_path.c_str());
if (!lock.try_lock())
throw std::runtime_error("Multiple instance");
std::cout << "Running" << std::endl;
while (true)
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}
int main(int argc, char *argv[])
{
namespace bipc = boost::interprocess;
if (argc < 2)
return 0;
std::string path = argv[1];
std::string lock_path = "/var/lock/" + path + ".lock";
{
std::ofstream stream(lock_path, std::ios::app);
}
bipc::file_lock lock(lock_path.c_str());
if (!lock.try_lock())
throw std::runtime_error("Multiple instance");
std::cout << "Running" << std::endl;
while (true)
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}