按值返回由互斥锁保护的shared_ptr是否安全?

发布于 2024-12-09 01:47:40 字数 402 浏览 0 评论 0原文

下面是一个代码示例:

class A {
  boost::mutex a_mutex;
  boost::shared_ptr<int> a;

  boost::shared_ptr<int> clone_a(void) {
    boost::lock_guard<boost::mutex> lock(a_mutex);
    return a;
  }
};

建议对 A::aboost::shared_ptr 复制构造函数调用将先于 boost::lock_guard > 尽管编译器优化,析构函数调用。 那么,调用 A::clone_a() 是否安全?

Here is a code sample:

class A {
  boost::mutex a_mutex;
  boost::shared_ptr<int> a;

  boost::shared_ptr<int> clone_a(void) {
    boost::lock_guard<boost::mutex> lock(a_mutex);
    return a;
  }
};

The suggestion is that the boost::shared_ptr copy constructor call on A::a will precede the boost::lock_guard destructor call despite of the compiler optimizations.
So, is it safe to call A::clone_a() ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝礼 2024-12-16 01:47:40

如果“安全”意味着您不会在 a 上发生数据争用,那么是的。正是如你所说。

但是,您可能知道,它不会保护对 *a (或 *clone_a())的进一步访问。我不确定为什么该方法被称为“克隆”,因为它不克隆任何东西。

If by "safe" you mean you won't get data races on a, then yes. It is exactly as you say.

However, it won't protect further accesses to *a (or *clone_a()), as you probably know. I'm not sure, why is the method called "clone", as it doesn't clone anything.

如梦亦如幻 2024-12-16 01:47:40

是的,这段代码是安全的。如果您参考 shread_ptr 线程安全,您可以看到,对线程本地shared_ptr对象的线程写访问就很好了。

在上面的代码中,对成员shared_ptr的访问需要锁,因为它可以被多个线程访问。到返回临时对象的复制是在锁内完成的,因此您在那里是安全的。该临时对象无法被其他线程看到,因此此时您可以安全地将其复制到其他共享指针。

现在,选择clone_a作为函数名可能是错误的。您没有克隆底层对象,您只是获得了shared_ptr的副本。所以我假设您打算共享相同的底层“int”。

Yes, this code is safe. If you refer to shread_ptr Thread-Safety you can see that threaded write access to thread-local shared_ptr objects is just fine.

In your code above the access to the member shared_ptr requires the lock, since it could be accessed by multiple threads. The copy to the return temporary is done within the lock, thus you're safe there. That temporary cannot be seen by other threads so at that point you are safe to copy it to other shared_ptr's.

Now perhaps the choice of clone_a as a function name is wrong. You aren't cloning the underlying object, you are simply getting a copy of the shared_ptr. So I am assuming you intend on sharing the same underlying "int".

苍白女子 2024-12-16 01:47:40

如果您使用返回值则不会。返回值本身是一个
临时的,其生命周期超出了函数的结尾;它
将在调用的完整表达式的末尾被破坏
A::clone_a。因此,如果您编写类似: 的内容

shared_ptr<int> newA = object->clone_a();

,形式语义将适用于由
object->clone_a() 被复制到 newA 中,在
调用者(因此不受互斥锁的保护)。在这种特殊情况下,您
可能会因为 RVO 而逃脱惩罚,但这不一定是
情况,还有其他情况 RVO 无法干预。

如果您担心的只是指针的副本,我很确定
如果您设置正确的编译器选项(-D
somthing
),boost::shared_ptr 将以原子方式运行。在
在这种情况下,您根本不需要互斥锁。

Not if you use the return value. The return value itself is a
temporary, whose lifetime extends beyond the end of the function; it
will be destructed at the end of the full expression which calls
A::clone_a. So if you write something like:

shared_ptr<int> newA = object->clone_a();

, the formal semantics will be for the temporary returned by
object->clone_a() to be copied into newA, in the context of the
caller (and so unprotected by the mutex). In this particular case, you
may get away with it because of RVO, but that won't necessarily be the
case, and there are other cases where RVO can't intervene.

If all you're worried about is the copy of the pointer, I'm pretty sure
that if you set the right compiler options (-D
somthing
), boost::shared_ptr will behave atomically. In
this case, you don't need the mutex at all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文