def*_*ode 13 c++ concurrency mutex semaphore c++11
我需要两个线程以"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 );
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用互斥锁(在技术上是一个二进制信号量)做同样的事情,它有一个奇怪的代码气味.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为气味是互斥不是为了将信息传达给另一个线程.(c ++ 11标准委员会添加了一个虚假的try_lock失败来阻止意外的信息传输;§30.4.1/ 14.)似乎互斥体是为了同步对变量的访问,然后可以将信息传递给另一个线程.
最后,当使用a实现时std::condition_variable,它看起来是正确的,但它更复杂(tick_vs_tock变量,互斥锁和条件变量).为简洁起见,我省略了实现,但它确实是直截了当的.
互斥解决方案是否正常?或者它有什么巧妙的错误吗?
有没有一个很好的模式来解决我没有想到的嘀嗒/嘀嗒问题?
Foz*_*ozi 12
Mutex不仅仅是一个二进制信号量,它还有一个限制,即只允许锁定线程解锁它.
你违反了这条规则.
编辑:
来自MSDN:
如果调用线程不拥有互斥对象,则ReleaseMutex函数将失败.
从谷歌出现的一些网站pthread_mutex_unlock:
如果出现以下情况,pthread_mutex_unlock()函数可能会失败:
EPERM当前线程不拥有互斥锁.
您将在其他互斥实现中找到相同的内容.这是有道理的,因为互斥锁应该保护线程对资源的访问权限,因此另一个线程不应该能够解锁它.
Ste*_*sop 10
由于您有一个使用信号量的情况,我认为修复是使用互斥锁和条件变量来移植实现一个.
这可能不是特别有效(因为它将使用每个信号量的互斥/ condvar对),但是您可以在具有自己的信号量的系统(例如Posix和Windows)上切换备用实现.
显然,信号量"太容易出错".尽管对Boost充满敬意,但我认为至少我们中的一些人可以管理.当然,你可以把自己绑在试图用多个信号量做复杂事情的结上,而且它们是一个非常低级的工具.但是,当他们是正确的,没有问题.
| 归档时间: |
|
| 查看次数: |
5230 次 |
| 最近记录: |