我遇到了一个情况,有两个不同的进程(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迷,我觉得让这样的代码运行令人不安。
当然,我不指望这里有人给我写出解决方案,但如果有人知道一个可靠的代码链接,我会很高兴使用它。 附:数据文件的访问不是读者、写者、读者、写者...它可以是读者、读者、写者、写者、写者、读者、写者... 另一个进程不是用C++编写的,所以boost不在考虑范围内。