我建议锁定如此细粒度的级别可能(方式)过度杀伤力。
我建议对 IrcUser 对象本身进行原子更新,这可能是无锁取决于您的库实现和目标架构。这是一个使用的示例
std::atomic_is_lock_free<std::shared_ptr>
std::atomic_load<std::shared_ptr>
std::atomic_store<std::shared_ptr>
See http://en.cppreference.com/w/cpp/memory/shared_ptr/atomic用于文档。
免责声明 我不知道有多少编译器/C++ 库实现已经实现了这个 C++11 功能。
它看起来像这样:
#include <atomic>
#include <memory>
#include <string>
struct IrcSubject {};
typedef char c8;
typedef uint16_t u16;
typedef u16 mode_update;
class IrcUser : public IrcSubject
{
private:
// ...
std::string _nickname;
std::string _ident;
std::string _hostmask;
u16 _modes;
public:
IrcUser(std::string nickname, std::string ident, std::string hostmask, u16 modes)
: _nickname(nickname), _ident(ident), _hostmask(hostmask), _modes(modes) { }
// ...
std::string const& Ident() const { return _ident; }
std::string const& Hostmask() const { return _hostmask; }
const u16 Modes() const { return _modes; }
std::string const& Nickname() const { return _nickname; }
};
//IrcUser.cc
bool Update(std::shared_ptr<IrcUser>& user,
std::string new_nickname,
std::string new_ident,
std::string new_hostmask,
const mode_update *new_modes
)
{
auto new_usr = std::make_shared<IrcUser>(std::move(new_nickname), std::move(new_ident), std::move(new_hostmask), *new_modes /* ??? */);
std::atomic_store(&user, new_usr);
//Notify(SN_NicknameChange, new_nickname);
return true;
}
bool Foo(IrcUser const& user)
{
// no need for locking, user is thread safe
}
int main()
{
auto user = std::make_shared<IrcUser>("nick", "ident", "hostmask", 0x1e);
mode_update no_clue = 0x04;
Update(user, "Nick", "Ident", "Hostmask", &no_clue);
{
auto keepref = std::atomic_load(&user);
Foo(*keepref);
}
}