我需要两个线程以 “tick tock” 模式进行。当使用信号量实现时,这看起来很好:
Semaphore tick_sem(1);
Semaphore tock_sem(0);
void ticker( void )
{
while( true )
{
P( tick_sem );
do_tick();
V( tock_sem );
}
}
void tocker( void )
{
while( true )
{
P( tock_sem );
do_tock();
V( tick_sem );
}
}
但是,如果我对互斥体(从技术上讲是二进制信号量)做同样的事情,它会有一种奇怪的代码气味。
std::mutex tick_mutex;
std::mutex tock_mutex;
tock_mutex.lock();
void ticker( void )
{
while( true )
{
tick_mutex.lock();
do_tick();
tock_mutex.unlock();
}
}
void tocker( void )
{
while( true )
{
tock_mutex.lock()
do_tock();
tick_mutex.unlock();
}
}
我认为这种气味是互斥体并不意味着将信息传达给另一个线程。 (c++11 标准委员会在 try_lock 中添加了一个虚假的失败,以阻止意外的信息传输;§30.4.1/14。)似乎互斥锁旨在同步对变量的访问,然后可以将信息传递给另一个线程。
最后,当使用 std::condition_variable
实现时,它看起来正确但更复杂(tick_vs_tock 变量、互斥体和条件变量)。为简洁起见,我省略了实现,但它真的很简单。
互斥体解决方案好吗?还是有什么微妙的问题?
有没有一个很好的模式来解决我没有想到的滴答/滴答问题?
最佳答案
互斥量不仅仅是一个二进制信号量,它还有一个限制,就是只允许锁定线程解锁它。
你违反了这条规则。
编辑:
来自 MSDN :
The ReleaseMutex function fails if the calling thread does not own the mutex object.
来自谷歌搜索到的某个网站pthread_mutex_unlock :
The pthread_mutex_unlock() function may fail if:
EPERM The current thread does not own the mutex.
您会在其他互斥体实现中发现相同的情况。这是有道理的,因为互斥锁应该保护线程对资源的访问,所以另一个线程不应该能够解锁它。
关于c++ - 使用互斥锁作为信号量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6804044/