奇怪的C++11互斥行为
我正在尝试使用二进制信号量实现计数信号量 代码逻辑是众所周知的,在使用Qt的QMutex类之前已经对其进行了测试,并且已知它可以使用生产者-消费者多线程驱动程序进行正确测试。 我已经尝试过手动控制l互斥锁来锁定类、锁定保护和唯一锁定对象,但没有效果 尽管如此,调用acquire的线程似乎在块互斥上被阻塞,即使其他线程调用block.unlock也是如此。使代码工作的唯一方法是将block.lock行替换为whileblock.try\u lock;然后一切正常 如果我用一个条件变量替换块互斥体,代码就会工作奇怪的C++11互斥行为,c++,multithreading,c++11,mutex,C++,Multithreading,C++11,Mutex,我正在尝试使用二进制信号量实现计数信号量 代码逻辑是众所周知的,在使用Qt的QMutex类之前已经对其进行了测试,并且已知它可以使用生产者-消费者多线程驱动程序进行正确测试。 我已经尝试过手动控制l互斥锁来锁定类、锁定保护和唯一锁定对象,但没有效果 尽管如此,调用acquire的线程似乎在块互斥上被阻塞,即使其他线程调用block.unlock也是如此。使代码工作的唯一方法是将block.lock行替换为whileblock.try\u lock;然后一切正常 如果我用一个条件变量替换块互斥体,
#include <mutex>
class semaphore
{
private:
int value=0;
std::mutex l, block;
public:
semaphore(int i=0);
semaphore(const semaphore&)=delete;
semaphore(const semaphore&&)=delete;
semaphore & operator=(const semaphore&)=delete;
semaphore & operator=(const semaphore&&)=delete;
void acquire();
void acquire(unsigned int i);
void release(unsigned int i=1);
int available();
bool try_acquire(unsigned int i=1);
};
//---------------------------------
semaphore::semaphore(int i)
{
value=i;
block.lock(); // make sure that any thread trying to lock will block
}
//---------------------------------
void semaphore::acquire()
{
l.lock();
value--;
if(value <0)
{
l.unlock(); // release the semaphore while waiting
while( block.try_lock()); // LINES IN QUESTION
//block.lock(); // LINES IN QUESTION
}
else
l.unlock();
}
//---------------------------------
void semaphore::acquire(unsigned int i)
{
while(i--)
this->acquire();
}
//---------------------------------
void semaphore::release(unsigned int i)
{
l.lock();
while(i--)
{
value++;
if(value <=0)
block.unlock();
}
l.unlock();
}
//---------------------------------
int semaphore::available()
{
std::unique_lock<std::mutex> guard(l);
return value;
}
//---------------------------------
bool semaphore::try_acquire(unsigned int i)
{
l.lock();
bool res=false;
if(value>=(int)i)
{
value-=i;
res=true;
}
l.unlock();
return res;
}
未定义的行为:
已经拥有互斥锁的线程无法调用try_lock,否则,行为未定义。线路阻塞时。尝试锁定;这是不正确的。
unlock只能由拥有互斥锁的线程调用,否则,行为未定义。
2也错了。如果代码起作用,那是一次意外
您需要一个适当的信号量实现,这是部分涉及的。永远不要手动调用lock或unlock。相反,如果出于某种原因提前离开作用域,那么使用互斥锁可能会导致死锁。注意:互斥锁不是二进制信号量。如果您有一个二进制信号量或计数信号量,那么您可以像互斥一样使用它,但反过来则不正确。二进制信号量可以以互斥不能的方式使用。下面StaceyGirl的回答描述了一些你可以用二进制信号量做的事情,而用互斥器做不到。谢谢大家。非常感谢。