【发布时间】:2011-06-03 15:10:21
【问题描述】:
我有一个情况,其中 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;
}
};
用法:
ReadStatus readStatus; //RAII FTW
if ( ! readStatus.OKToRead())
return;
这是针对一个程序的,其他的将有类似的类。 想法是: 1.检查其他程序是否创建了他的“我是所有者文件”,如果它有中断,则转到2。 2.创建我的“我是所有者”文件,再次检查其他程序是否创建了他自己的文件,如果它删除了我的文件并中断,则转到3。 3. 做我的阅读,然后删除我的“我是所有者文件”。
请注意,当他们不读或不写时很少发生是可以的,但问题是我仍然看到竞争条件的可能性很小,因为理论上其他程序可以检查我的锁定文件是否存在,看到没有一,然后我创建我的,其他程序创建他自己的,但是在 FS 创建他的文件之前,我再次检查,它不存在,然后灾难发生。这就是我添加一秒延迟的原因,但作为一个 CS 书呆子,我发现运行这样的代码令人不安。 Ofc 我不希望这里有人给我写一个解决方案,但如果有人知道我可以使用的可靠代码的链接,我会很高兴。 附言它必须是文件,因为我不是在编写整个项目,这就是它的安排方式。
P.P.S.: 访问数据文件不是 reader,writer,reader,writer.... 可以是 reader,reader,writer,writer,writer,reader,writer....
P.P.S:其他进程不是用 C++ 编写的 :(,所以 boost 是不可能的。
【问题讨论】:
-
为什么要重新发明轮子而不是封装操作系统提供的锁定原语?
-
@aix - 就像我说我不是在编写整个项目,也不是在设计它。 Ofc 如果没有人用“FS mutex”魔法回答,我会哭,然后要求更改设计,或者希望超时提供足够好的可能性来避免竞争条件。
标签: c++ filesystems race-condition