c 11 – 使用std :: unique_ptr / std :: shared_ptr确认线程安
发布时间:2020-12-16 10:33:26 所属栏目:百科 来源:网络整理
导读:我的应用程序有一个基本上是普通客户端的IRC模块.由于这是严格的线程,我冒着插件检索的风险,例如,用户昵称 – 它当时有效,但解析器触发更新,更改所述昵称. 一旦另一个线程再次执行,它就会处理一个指向现在无效内存的指针,因为它不可能将返回副本作为原子操作
我的应用程序有一个基本上是普通客户端的IRC模块.由于这是严格的线程,我冒着插件检索的风险,例如,用户昵称 – 它当时有效,但解析器触发更新,更改所述昵称.
一旦另一个线程再次执行,它就会处理一个指向现在无效内存的指针,因为它不可能将返回副本作为原子操作. 基于以下代码,我的假设是正确的吗?因此,我想我必须使用通常的互斥锁定/解锁方法,除非有人可以确认或建议否则(我宁愿不必转换并返回shared_ptr,但我想这是一个有效的选项,它是只是我打算SWIG这个,不知道它是否不喜欢它们. 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 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); } ... } 解决方法
代码具有竞争条件,因此具有未定义的行为,因为在同一对象上存在可能的读取( – > get())和写入(.reset()或=)(std :: shared_ptr< std来自不同线程的:: string> instance):必须同步对std :: shared_ptrs的访问.
注意在getter中锁定 纠正: >将一个std :: mutex添加到IrcUser(请注意,这使得该类不可复制): mutable std::mutex mtx_; // Must be mutable for use within 'const' >在getter和Update()中锁定std :: mutex,使用 std::shared_ptr<std::string> Nickname() const { std::lock_guard<std::mutex> l(mtx_); return _nickname; } bool IrcUser::Update(const c8 *new_nickname,const mode_update *new_modes) { if (new_nickname) { { std::lock_guard<std::mutex> l(mtx_); _nickname.reset(new std::string(new_nickname)); } // No reason to hold the lock here. Notify(SN_NicknameChange,new_nickname); } return true; } 如果复制是可接受的,请考虑使用std :: string,因为shared_ptr可能会增加不必要的复杂性. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |