gpt4 book ai didi

c++ - Boost Interprocess named_mutex 作为类成员

转载 作者:行者123 更新时间:2023-11-28 06:40:45 25 4
gpt4 key购买 nike

我有一个类被设计为一些 boost 共享内存的包装器。当我尝试将 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;
}

我在创建锁对象的构造函数中遇到错误,但我不明白为什么。我读到我必须定义自己的复制构造函数和赋值运算符,我已经做到了。有什么想法吗?

最佳答案

您收到错误是因为必须初始化互斥锁成员。

这是通过默认构造函数发生的。在这种情况下是私有(private)的。因此你得到错误(关于 boost::interprocess::named_upgradable_mutex named_upgradable_mutex() 的默认构造函数是私有(private)的)。

您所拥有的代码实际上会发生什么:在进入 SharedMemoryVal 构造函数的主体之前,将使用其默认构造函数初始化 mutex 成员。然后在正文中,您将把一个新构造的对象分配给互斥体成员。即使效率低下,只要 named_upgradable_mutex 的默认(无参数)构造函数是公共(public)的(将其设为私有(private)是有道理的,因为默认构造没有名称的互斥锁是毫无意义的)。

我建议您阅读 Scott Meyers 的 Effective C++(以及更有效的 C++)。如果您没有它们,我建议您购买它们。在 Effective C++ 第 1 章,第 4 项“确保对象在使用之前已初始化”中,您会得到类似的解释,说明如果在 ctor 主体中分配给成员变量(如上所述的默认构造+分配)与初始化会发生什么它们在初始化列表中(仅构造)。

在更有效的 C++ 中,您有两个项目。 第 12 条:在构造函数中优先初始化而不是赋值。

第 13 项:按照成员声明的顺序列出初始化列表中的成员。(这与下面关于初始化顺序的注释有关)更详细。

一些说明上述行为的在线 Material :Why preffer member initialization over assignment?

要解决此问题,请将互斥量的构造移至初始化列表。更多关于成员初始值设定项列表的信息在这里 Member initializer list

喜欢:

template< class T > SharedMemoryVal< T >::
SharedMemoryVal( const std::string &name, bool readOnly ) :
mutexName( name.append("_mutex") ),
mutex (open_or_create, mutexName.c_str() )
{
}

注意:请注意初始化顺序,确保mutexName先于mutex初始化。违反直觉的是,如果您在 SharedMemoryVal 类声明中的 mutex 之后声明 mutexName 成员,那么在使用它调用 mutex 构造函数时 mutexName 将未初始化,因为初始化是按照 header 中声明的顺序进行的,而不是按照成员初始化列表中的顺序进行的。在您的情况下,您在 mutex 之前声明了 mutexName,这样就可以了。只是不要将它的声明移到 header 中的互斥量之后......我想我也应该提到这一点。

关于c++ - Boost Interprocess named_mutex 作为类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26024527/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com