C++ 使用互斥量作为信号量?
我需要两个线程以“滴答”模式前进。当使用信号量实现时,这看起来很好:C++ 使用互斥量作为信号量?,c++,concurrency,c++11,mutex,semaphore,C++,Concurrency,C++11,Mutex,Semaphore,我需要两个线程以“滴答”模式前进。当使用信号量实现时,这看起来很好: 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
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标准委员会添加了一个虚假的失败尝试_lock来阻止意外的信息传输;§30.4.1/14。)看起来互斥锁是用来同步对变量的访问,然后可以将信息传递给另一个线程
最后,当使用std::condition_变量实现时,它看起来是正确的,但更复杂(tick_vs_tock变量、互斥体和条件变量)。为了简洁起见,我省略了实现,但它实际上是直截了当的
互斥解决方案好吗?还是有什么微妙的问题
有没有一种解决我没有想到的滴答声问题的好模式?互斥锁不仅仅是一个二进制信号量,它还有一个限制,即只允许锁定线程解锁它 你违反了那条规则 编辑: 发件人: 如果调用线程不拥有 互斥对象 从谷歌搜索的某个网站: 如果出现以下情况,pthread_mutex_unlock()函数可能会失败: EPERM当前线程不拥有互斥锁
在其他互斥实现中也会发现同样的情况。这是有道理的,因为互斥锁应该保护线程对资源的访问,所以另一个线程不应该能够解锁它。既然你有理由使用信号量,我认为修复方法是可移植的 这可能不是特别有效(因为每个信号量将使用互斥/condvar对),但您可以在具有自己的信号量的系统(如Posix和Windows)上切换其他实现
显然。恕我直言,我认为至少我们中的一些人能够做到。当然,你可以把自己绑在结上,它们是一个相当低级的工具。但是如果它们是正确的,就没有问题。BTW:这个问题只是因为C++0x没有
std::semaphore
而doublestd::mutex
解决方案比std::condition\u变量
解决方案更简单。(为什么)它对解锁()
线程中的互斥锁当前不存在?@Steve这是一个非常好的问题(提示,提示,轻推,轻推)。根据Steve的评论。这真的是一条规则吗?这绝对是个好主意。@deft-我认为这取决于互斥的实现,互斥依赖于系统。通常,解锁其他人的互斥锁不是一个好主意,即使系统允许。@deft_代码:我还没有阅读FDIS的互斥锁部分,但如果这不是一条规则,我会感到惊讶。互斥体有一个所有者,这是其作为同步工具的基本定义的一部分。我同意“太容易出错”的说法很奇怪。互斥体也可能容易出错。锤子也可以。