面试的时候经常被问到互斥量,条件变量和信号量之间的问题。比如前几天华为面试就被问到互斥量和信号量的区别,说到互斥量也可以使用一个二值信号量来实现,什么情况是只能使用互斥量而不能使用信号量的。这个问题当时我只回答出一种情况,想了解详情的可自行百度。如面试官所说,信号量可以实现互斥量,大部分情况下也可以实现条件变量。甚至使用信号量的实现远比其他实现更容易理解。然而很多时候使用信号量替换条件变量的可能会降低并发程序的性能。
下面是我自己实现的一个线程池的代码:
github地址
这个线程池内部维护一个同步队列,同步队列实现了阻塞的pop和push接口。当队列为空的时候,在一个_emptyCond条件变量上等待;当队列满的时候,在一个_fullCond条件变量上等待。
核心代码如下:
template<typename T>
T SyncQueue<T>::pop() {
bool wakePush = false;
T t;
{
ScopedLocker lock(_qMutex);
wakePush = (_q.size() == _capacity);
if (_q.empty()) {
pthread_cond_wait(&_emptyCond, &_qMutex);
}
wakePush |= (_q.size() == _capacity);

本文探讨了在面试中常见的互斥量、条件变量和信号量之间的区别,特别指出虽然信号量在大多数情况下能替代互斥量和条件变量,但在某些场景下,如线程池的实现,使用信号量可能会降低并发程序的性能。作者提供了一个线程池的实现,通过条件变量同步时,CPU平均使用率为93%,改用信号量同步后,CPU占用率降至83%,降低了10%。实际效果还需进一步验证。

799

被折叠的 条评论
为什么被折叠?



