我正在开发一个可执行文件系统,它们一起运行(并通过ROS通信)。我有一个。json配置文件,这是常见的所有可执行文件和libCommon。这是一个从。json中读取特定值的函数库。该库静态链接到CMakeLists.txt中的所有可执行文件:
set(NAME exec1)
target_link_libraries(${NAME} ... Common)
当系统启动时,所有的执行需要一个接一个地启动-类似于bash脚本:
./exec1 & ./exec2
等。
我使用的。json解析器给了我断言错误,我发现这是可执行文件运行其构造函数并同时访问相同配置文件的症状;
所以,我已经尝试了一些东西与一个全局互斥(std::mutex忙),这是在头中声明,并在libCommon.so.的cpp中定义。然后,它在每个函数的入口被锁定,在返回语句之前解锁:
构成
namespace jsonFunctions
{
extern std::mutex busy;
namespace ROS
{
extern double readRosRate( configFiles::fileID configID );
}
...
}
class ConfigFile
{
public:
ConfigFile( configFiles::fileID configID )
{
configFileFstream.open( configFiles::filePaths.at( configID ) );
if( configFileFstream.is_open() )
{
parsedFile.parse( configFileFstream );
}
}
~ConfigFile()
{
configFileFstream.close();
}
public:
jsonxx::Object parsedFile;
private:
std::fstream configFileFstream;
};
Common.cpp
namespace jsonFunctions
{
std::mutex busy;
namespace ROS
{
double readRosRate( configFiles::fileID configID )
{
busy.lock();
ConfigFile* desiredConfigFile = new ConfigFile( configID );
auto rosConfig = desiredConfigFile->parsedFile.get< jsonxx::Object >( "ROS" );
delete desiredConfigFile;
busy.unlock();
return rosConfig.get< jsonxx::Number >( "rate" );
}
但这不起作用。我应该如何阻止可执行文件访问配置文件在同一时间?
可执行文件存放在它们自己的内存空间中。它们不与其他可执行文件共享内存,即使它们使用相同的共享库1。
在标准c++中没有进程间互斥。你必须在标准之外找到一个进程间互斥锁。boost有它们,大多数操作系统文件系统api都可以用来创建它们。
一些操作系统api允许您以独占模式打开文件。其他依赖于您创建的显式锁。在某些情况下,此功能可能取决于您正在访问的文件系统,甚至取决于您访问它的方式。
显然,一种方法是在双方共享的特定位置打开open("unique_name.lock", O_CREAT|O_EXCL, 0777)
。在同一时间,只有一个进程可以以这种方式打开unique_name.lock
。
另一种是使用flock。
1好吧,只读页面有时被某些操作系统在进程之间共享;比如可执行代码。甚至读写页面也可以是写时复制共享。然而,这种分享只是"好像"发生的。这并没有发生。此外,地址空间布局的随机化使得这种优化不那么有用。