繁体   English   中英

奇怪的C ++ 11互斥行为

[英]Strange C++11 mutex behavior

我正在尝试使用二进制的实现计数信号量。

代码逻辑是众所周知的,并且在使用Qt的QMutex类之前已经过测试,并且可以正常工作(已使用生产者-消费者多线程驱动程序进行了测试)。 我尝试过手动控制l互斥锁(以锁定类), lock_guardunique_lock对象,但没有任何效果。

甚至当其他线程调用block.unlock()时,调用acquire()线程似乎也会在block互斥体上被block (尽管block.unlock() 使代码起作用的唯一方法是用while(block.try_lock());替换block.lock()while(block.try_lock()); 然后,一切正常。

如果我用条件变量替换block互斥锁,则该代码有效。

#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不能由已经拥有互斥锁的线程调用,否则,行为是不确定的。 while( block.try_lock()); 是不正确的。
  • 只有拥有互斥量的线程才能调用unlock ,否则行为是不确定的。

#2对于QtMutex也是错误的。 如果代码是“有效的”,那么它是偶然发生的。

您需要一个适当的信号量实现, 此处部分介绍了该实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM