我的应用程序有一个IRC模块,本质上是一个普通的客户端。由于这个模块有很多线程,我存在一种风险,即插件检索例如用户昵称-在那个时间是有效的,但解析器会触发更新,从而更改所说的昵称。一旦另一个线程再次执行,它就处理指向无效内存的指针,因为将返回+复制作为原子操作是不可能的。
基于下面的代码,我的假设是否正确?因此,我想我必须使用通常的互斥锁定/解锁方法,除非有人能够确认或建议其他方法(我宁愿不必转换并返回共享指针,但我想这是一个有效的选项,只是我打算SWIG'ing这个,不知道它是否喜欢它们)。
IrcUser.h
基于下面的代码,我的假设是否正确?因此,我想我必须使用通常的互斥锁定/解锁方法,除非有人能够确认或建议其他方法(我宁愿不必转换并返回共享指针,但我想这是一个有效的选项,只是我打算SWIG'ing这个,不知道它是否喜欢它们)。
IrcUser.h
class IrcUser : public IrcSubject
{
private:
...
std::shared_ptr<std::string> _nickname;
std::shared_ptr<std::string> _ident;
std::shared_ptr<std::string> _hostmask;
public:
...
const c8*
Ident() const
{ return _ident.get()->c_str(); }
const c8*
Hostmask() const
{ return _hostmask.get()->c_str(); }
const u16
Modes() const
{ return _modes; }
const c8*
Nickname() const
{ return _nickname.get()->c_str(); }
bool
Update(
const c8 *new_nickname,
const c8 *new_ident,
const c8 *new_hostmask,
const mode_update *new_modes
);
};
IrcUser.cc
bool
IrcUser::Update(
const c8 *new_nickname,
const c8 *new_ident,
const c8 *new_hostmask,
const mode_update *new_modes
)
{
if ( new_nickname != nullptr )
{
if ( _nickname == nullptr )
{
*_nickname = std::string(new_nickname);
}
else
{
_nickname.reset();
*_nickname = std::string(new_nickname);
}
Notify(SN_NicknameChange, new_nickname);
}
...
}
struct mode_update { bool erase_existing; u16 to_add; u16 to_remove; };
这是个很棒的概念 - 因为IrcUser是IrcChannel中的shared_ptr,这可能会非常好用 - 正如你所说,对于这个来说太多的锁定/解锁确实是过度的。我会试一试! - ZXcvbnM