2

考虑以下情况:

class SomeClass : public QObject
{
  Q_OBJECT
private:
    unsigned long long someVar;

public:
    unsigned long long getSomeVar(){
        return someVar;
    void threadFunc();
}

threadFunc()将在一个新线程中调用(你猜对了),它看起来像这样:

void SomeClass::threadFunc()
{
  ++someVar;
  // Do stuff...
}

现在,在另一个线程中,我想阅读someVar. 我通过调用来做到这一点getSomeVar()。但是,需要同步。我怎么做?对于拥有 的线程somevar,同步并不难。只会是

void SomeClass::threadFunc()
{
  mut.lock();
  ++someVar;
  mut.unlock();
  // Do stuff...
}

QMutex mut在类声明中添加了一个。但是我如何同步getSomeVar()?我不能只说:

unsigned long long getSomeVar(){
  mut.lock();
  return someVar;
  mut.unlock();
}

mut.unlock()由于之前的 - 语句,将永远不会被调用return

我知道通常通过写作来避免这种冲突......

unsigned long long getSomeVar(){
  QMutex mut;
  // mut-constructor calls mut.lock()
  return someVar;
  // mut-destructor calls mut.unlock()
}

...但在这种情况下,我需要互斥锁在内部getSomeVar()threadFunc(). 我试过

unsigned long long getSomeVar(){
  // constructing mutex from mut (which is the class' mutex)
  QMutex mutex(mut);
  // mutex-constructor calls mut.lock()
  return someVar;
  // mutex-destructor calls mut.unlock()
}

但是 mutex 的复制构造函数是私有的。

我可以在这里做什么?

4

2 回答 2

7

您正在寻找QMutexLocker

{
    QMutexLocker locker(&mut);
    ...
}

// Goes out of scope, unlocks the mutex in its destructor
于 2013-04-05T21:15:31.907 回答
2

您将互斥锁混淆了:每个可保护变量只有一个互斥锁,但可能有很多尝试锁定它!

您需要一个单独的锁类,其中每个线程有一个实例:

struct Lock
{
    QMutex & m_;
    Lock(QMutex & m) : m_(m) { m_.lock(); }
    ~Lock() { m_.unlock();}
};

用法:

QMutex mutex;

void thread_function()
{
    Lock lk(mut);
    critical_operation();
}   // unlocks "mutex" as if by magic

Qt 可能已经为您提供了这样一个类。(标准库也这样做:因为std::mutex你有std::lock_guard<std::mutex>。)

于 2013-04-05T21:15:37.683 回答