NoS*_*tAl 5 c++ filesystems race-condition
我有一种情况,其中2个不同的进程(我的C++,其他由JAVA中的其他人完成)是来自某些共享数据文件的编写者和读者.所以我试图通过编写这样的类来避免竞争条件(编辑:这个代码坏了,它只是一个例子)
class ReadStatus
{
bool canRead;
public:
ReadStatus()
{
if (filesystem::exists(noReadFileName))
{
canRead = false;
return;
}
ofstream noWriteFile;
noWriteFile.open (noWriteFileName.c_str());
if ( ! noWriteFile.is_open())
{
canRead = false;
return;
}
boost::this_thread::sleep(boost::posix_time::seconds(1));
if (filesystem::exists(noReadFileName))
{
filesystem::remove(noWriteFileName);
canRead= false;
return;
}
canRead= true;
}
~ReadStatus()
{
if (filesystem::exists(noWriteFileName))
filesystem::remove(noWriteFileName);
}
inline bool OKToRead()
{
return canRead;
}
};
Run Code Online (Sandbox Code Playgroud)
用法:
ReadStatus readStatus; //RAII FTW
if ( ! readStatus.OKToRead())
return;
Run Code Online (Sandbox Code Playgroud)
这是一个程序ofc,其他将有类似的类.想法是:1.检查其他程序是否创建了他的"我是所有者文件",如果它已经中断,则转到2. 2.创建我的"我是所有者"文件,再次检查其他程序是否创建了自己的,如果它已删除我的文件并打破其他,请转到3. 3.执行我的阅读,然后删除我的"我是所有者文件".
请注意,当它们都不读或写时很少出现,但问题是我仍然看到竞争条件的可能性很小,因为理论上其他程序可以检查我的锁文件的存在,看到没有一个,然后我创建了我的,其他程序创建了自己的程序,但在FS创建他的文件之前我再次检查,它不存在,然后发生灾难.这就是为什么我添加了一秒延迟,但作为CS书呆子,我发现让代码运行起来令人不安.Ofc我不希望这里的任何人给我写一个解决方案,但如果有人知道我可以使用的可靠代码的链接,我会很高兴.PS它必须是文件,因为我不是在编写整个项目,而是它是如何安排完成的.
PPS:访问数据文件不是读者,作者,读者,作家....它可以是读者,读者,作家,作家,作家,读者,作家....
PPS:其他进程不是用C++编写的:(因此提升是不可能的.
在Unices上,传统的基于纯文件系统的锁定方法是使用带有mkdir()和的专用锁文件rmdir(),可以通过单个系统调用以原子方式创建和删除.您可以通过从不为锁的存在,明确地测试---而不是你总是尽量避免比赛采取了锁.所以:
lock:
while mkdir(lockfile) fails
sleep
unlock:
rmdir(lockfile)
Run Code Online (Sandbox Code Playgroud)
我相信这甚至适用于NFS(这通常很糟糕).
但是,您可能还希望查看正确的文件锁定,这样可以更好地加载; 我在Linux上使用F_SETLK/F_UNLCK fcntl锁(注意这些与flock锁不同,尽管结构的名称).这允许您正确阻止,直到释放锁定.如果应用程序死亡,这些锁也会自动释放,这通常是一件好事.此外,这些将允许您直接锁定共享文件,而无需单独的锁定文件.这也适用于NFS.
Windows具有非常相似的文件锁定功能,并且它还具有易于使用的全局命名信号量,这些信号量非常便于进程之间的同步.