我正在開發一個一起運行的可執行檔案系統(并通過 ROS 進行通信)。我有一個 .json 組態檔,它對所有可執行檔案都是通用的,還有一個 libCommon.so,它是一個從 .json 讀取某些值的函式庫。該庫靜態鏈接到 CMakeLists.txt 中的所有可執行檔案:
set(NAME exec1)
target_link_libraries(${NAME} ... Common)
當系統啟動時,所有的 exec 都需要一個接一個地啟動——就像 bash 腳本中的那樣:
./exec1 & ./exec2
等等。
問題
我使用的 .json 決議器給了我斷言錯誤,我發現這是可執行檔案運行其建構式并立即訪問相同組態檔的癥狀;
所以,我嘗試了一些帶有全域互斥鎖(std::mutex busy)的東西,它在頭檔案中宣告并在 libCommon.so 的 cpp 中定義。然后,它在每個函式的入口處被鎖定,并在 return 陳述句之前解鎖:
通用檔案
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;
};
通用檔案
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" );
}
但這不起作用。我應該如何阻止可執行檔案同時訪問組態檔?
uj5u.com熱心網友回復:
可執行檔案存在于它們自己的記憶體空間中。它們不與其他可執行檔案共享記憶體,即使它們都使用相同的共享庫1。
標準 C 中沒有行程間互斥鎖。您必須從標準之外找到行程間互斥鎖。
boost 有它們,大多數作業系統檔案系統 API 都可以用來創建它們。
某些作業系統 API 允許您以獨占模式打開檔案。其他人依賴于您創建的顯式鎖。在某些情況下,此功能可能取決于您訪問的檔案系統,甚至您訪問它的方式。
顯然,一種方法是open("unique_name.lock", O_CREAT|O_EXCL, 0777)在你們共同分享的特定地點打開。一次只能unique_name.lock以這種方式打開一個行程。
另一個是使用flock。
1好吧,某些作業系統有時會在行程之間共享只讀頁面;比如可執行代碼。甚至讀寫頁面也可以在寫時復制共享。然而,這種共享只是“好像”沒有發生。此外,地址空間布局隨機化使得這種優化不太有用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/336859.html
