4

假设我有一个类 foo:

class foo {
    static uint32 count_;
    pthread_mutex_t mu;

    void increase() {
      pthread_mutex_lock(&mu);
      count_++;
      pthread_mutex_unlock(&mu);
    }
}

如果我不使用互斥体,而只有一个 std::atomic 作为 count_,有什么区别吗?

谢谢!

4

2 回答 2

6

这是个很大的差异。pthread_mutex_lock可能非常昂贵,因为它可能包含系统调用*。原子增量产生lock xadd.

另一个优点是std::atomic<...>可能更好的可移植性,因为它是 C++ 标准的一部分。Pthread 调用很可能在 Windows 中不起作用。

*) 如果锁已被其他线程持有,则让当前线程休眠。但很可能只会发生自旋锁

于 2013-02-27T01:29:46.437 回答
4

互斥锁很可能实际上是作为一个原子增量实现的,如果你运气不好,在锁上发生争用,还涉及系统调用[当然,假设它不是一个系统无论哪种方式都可以打电话!]。

x86 上的原子解决方案将是一个简单的“加锁”操作。在其他处理器上它可能更复杂,但即便如此,原子是互斥体所需的最低限度,所以无论如何你至少有这么多的工作量。

然后添加互斥锁解锁,它可能没有那么复杂,但它不会完全免费。

所以,是的,选择原子。

但就像所有与性能有关的事情一样,测量“之前”和“之后”,看看它确实提高了性能。

请注意,我看到有人解释说,最初的 gnu C++ 标准库实现实际上是在操作周围使用某种互斥锁完成的,但我相信如果你有一个相当新的 g++ 版本,它应该没问题(至少对于 x86 类型的处理器) )。微软长期以来一直支持适当的原子操作作为内置,所以应该没问题。其他处理器架构可能会有所不同。

于 2013-02-27T01:42:05.973 回答