Home > Net >  Accessing only one executable at a time to a function in .so library
Accessing only one executable at a time to a function in .so library

Time:10-26

I'm developing a system of executables which run together (and communicate via ROS). I have a .json configuration file which is common for all the executables and a libCommon.so which is a library of functions to read certain values from the .json. The library is linked statically to all the executables in CMakeLists.txt:

set(NAME exec1)
target_link_libraries(${NAME} ... Common)

As the system is launching, all the execs need to start one after another - something like that in bash script:

./exec1 & ./exec2

etc.

The problem

The .json parser which I use is giving me assertion errors which I found out to be symptoms of the executables running their constructors and accessing the same config file at once;

So, I have tried some stuff with a global mutex (std::mutex busy), which is declared in the header and defined in cpp of the libCommon.so. Then, it is locked on entry of every function and unlocked before return statement:

Common.h

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" );
}

But this doesn't work. How am I supposed to block the executables from accessing the config file at the same time?

CodePudding user response:

Executables live in their own memory space. They do not share memory with other executables, even if they are both using the same shared library1.

There are no interprocess mutexes in standard C . You have to find an interprocess mutex from outside the standard.

boost has them, and most OS file system APIs can be used to create them.

Some OS APIs allow you to open files in an exclusive mode. Others rely on you created explicit locks. In some cases, this functionality may depend on the filesystem you are accessing, and even how you are accessing it.

Apparently one way to do it is to open open("unique_name.lock", O_CREAT|O_EXCL, 0777) in a specific spot you both share. Only one process can have unique_name.lock open in this way at a time.

Another is to use flock.


1 Well, read only pages are sometimes shared by some OS's between processes; like executable code. And even read-write pages can be copy-on-write shared. This kind of sharing, however, happens just "as if" it didn't happen. Also, address space layout randomization makes this optimization less useful.

  • Related