[英]Boost Interprocess named_mutex as a class member
我有一個類設計為一些增強共享內存的包裝器。 當我嘗試將named_mutex作為類成員並將其在構造函數中初始化時,出現編譯錯誤。 以下是相關代碼:
template< class T > class SharedMemoryVal
{
public:
SharedMemoryVal( const std::string &name, bool readOnly );
SharedMemoryVal( const SharedMemoryVal& other )
{
name = other.name;
mutexName = other.mutexName;
permissions = other.permissions;
shm = other.shm;
mutex = boost::interprocess::named_upgradable_mutex( boost::interprocess::open_or_create, mutexName.c_str() );
}
const SharedMemoryVal& operator=( const SharedMemoryVal& other )
{
if( this == &other )
return *this;
name = other.name;
mutexName = other.mutexName;
permissions = other.permissions;
shm = other.shm;
mutex = boost::interprocess::named_upgradable_mutex( boost::interprocess::open_or_create, mutexName.c_str() );
}
int8_t GetVal( T *val );
int8_t SetVal( T val );
virtual ~SharedMemoryVal();
private:
std::string name;
std::string mutexName;
boost::interprocess::mode_t permissions;
boost::interprocess::shared_memory_object shm;
mutable boost::interprocess::named_upgradable_mutex mutex;
};
using namespace boost::interprocess;
/**
* Construct new shared memory data value
* @param[in] name - Name of shared memory segment
* @param[in] readOnly
*/
template< class T > SharedMemoryVal< T >::SharedMemoryVal( const std::string &name, bool readOnly )
{
// Set name
this->name = name;
// Create mutex
mutexName = this->name.append( "_mutex" );
/* GETTING AN ERROR HERE */
/* error: \u2018boost::interprocess::named_upgradable_mutex::named_upgradable_mutex()\u2019 is private*/
mutex = named_upgradable_mutex( open_or_create, mutexName.c_str() );
//Create a shared memory object.
if( readOnly )
{
permissions = read_only;
shm = shared_memory_object( open_only, name.c_str(), read_only );
}
else
{
permissions = read_write;
shm = shared_memory_object( create_only, name.c_str(), read_write );
// Set size
shm.truncate( sizeof(T) );
}
}
template< class T > SharedMemoryVal< T >::~SharedMemoryVal()
{
shared_memory_object::remove( name.c_str() );
named_upgradable_mutex::remove( mutexName.c_str() );
}
/**
* Return current data value
* @return current data value
*/
template< class T > int8_t SharedMemoryVal< T >::GetVal( T *val )
{
int8_t retVal = -1;
//Map the whole shared memory in this process
mapped_region region( shm, permissions );
// Get data pointer
T *data = static_cast< T * >( region.get_address() );
// Lock
{
// This will only lock if someone else is writing.
// Multiple processes can read at the same time
sharable_lock< named_upgradable_mutex > lock( mutex );
// If there wasn't a problem getting the data
if( data != NULL )
{
*val = *data;
retVal = 0;
}
}
return retVal;
}
/**
* Set shared memory data value
* @param[in] val - value to set
*/
template< class T > int8_t SharedMemoryVal< T >::SetVal( T val )
{
int8_t retVal = -1;
//Map the whole shared memory in this process
mapped_region region( shm, permissions );
// Get data pointer
T *data = static_cast< T * >( region.get_address() );
// Do lock
{
// Lock will always be unlocked at the end of this block
scoped_lock< named_upgradable_mutex > lock( mutex );
// If we got the data OK
if( data != NULL )
{
*data = val;
retVal = 0;
}
}
return retVal;
}
我在創建鎖定對象的構造函數中遇到錯誤,但我不知道為什么。 我讀到我必須定義自己的副本構造函數和賦值運算符,而我已經做到了。 有任何想法嗎?
您收到錯誤,因為必須初始化互斥成員。
這是通過默認構造函數發生的。 在這種情況下是私有的。 因此,您會收到錯誤消息(關於boost :: interprocess :: named_upgradable_mutex的默認構造函數named_upgradable_mutex()是私有的)。
您擁有的代碼實際將發生的事情是:在進入SharedMemoryVal構造函數的主體之前,將使用其默認構造函數初始化互斥成員。 然后,在主體中,您將為互斥對象分配一個新構造的對象。 哪怕效率低下,只要named_upgradable_mutex的默認(無參數)構造函數是公共的,它就可以工作(將其設為私有是有意義的,因為默認構造不帶名稱的互斥體是沒有意義的)。
我建議您閱讀Scott Meyers的Effective C ++(以及更有效的C ++)。 如果您沒有它們,我建議您購買它們。 在有效的C ++第1章,第4項“確保在使用對象之前確保對象已初始化”中,您將獲得類似的解釋,說明在ctor主體中將變量分配給成員變量(如上所述的默認構造+賦值)而不是初始化的情況。它們在初始化列表中(僅用於構造)。
在更有效的C ++中,您有兩項。 項目12:在構造函數中,初始化優先於賦值。
和
第13項:按照聲明的順序在初始化列表中列出成員。 (這與下面有關初始化順序的注釋有關)更詳細。
一些在線材料說明了上述行為: 為什么將成員初始化優先於分配?
要解決此問題,請將互斥鎖的構造移至初始化程序列表。 有關成員初始化程序列表的更多信息,這里成員初始化程序列表
喜歡:
template< class T > SharedMemoryVal< T >::
SharedMemoryVal( const std::string &name, bool readOnly ) :
mutexName( name.append("_mutex") ),
mutex (open_or_create, mutexName.c_str() )
{
}
注意:請注意初始化順序,並確保在互斥對象之前已初始化了mutexName。 違反直覺的是,如果您在SharedMemoryVal類聲明中的互斥鎖之后聲明了互斥鎖成員,則在使用互斥鎖構造函數調用互斥鎖構造函數時,該互斥鎖將未初始化,因為初始化是按照標頭中聲明的順序進行的,而不是按成員初始化器列表的順序進行。 在您的情況下,您在互斥對象之前聲明了mutexName,這樣就可以了。 只是不要在標頭中的互斥量之后移動它的聲明。以為我也應該提到這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.