假设我有一个类foo:
class foo {
static uint32 count_;
pthread_mutex_t mu;
void increase() {
pthread_mutex_lock(&mu);
count_++;
pthread_mutex_unlock(&mu);
}
}
如果我不使用互斥锁,但是只有一个std :: atomic作为计数_是否有任何区别?
谢谢!
答案 0 :(得分:6)
存在巨大差异。 pthread_mutex_lock
可能非常昂贵,因为它可能包含系统调用*。原子增量产生lock xadd
。
另一个优点是std::atomic<...>
可能更好的可移植性,因为它是C ++标准的一部分。 Pthread调用很可能在Windows中不起作用。
*)如果某个其他线程已经持有锁,则让当前线程休眠。但很可能只会发生spinlock。
答案 1 :(得分:4)
互斥锁很可能实际上是作为一个原子增量实现的,如果你运气不好就会对锁进行争用,也会涉及系统调用[假设当然,它不是'无论如何系统调用!]。
x86上的原子解决方案将是一个简单的“锁定添加”操作。在其他处理器上它可能更复杂,但即便如此,原子是互斥量所需的最小值,因此无论如何你至少要有这么多的工作量。
然后你添加互斥锁解锁,这可能不是那么复杂,但它不会完全免费。
所以,是的,去原子。
但是就像所有与性能有关的事情一样,请测量“之前”和“之后”,看看它确实提高了性能。
请注意,我看到有人解释说原来的gnu C ++标准库实现实际上是在操作中使用某种互斥量来完成的,但我相信如果你有一个合理的g ++版本它应该没问题(至少对于x86型处理器)。微软很长一段时间都支持内置的正确的原子操作,所以应该没问题。其他处理器架构可能有所不同。