问题 Qt同步障碍?


Qt是否等同于同步障碍?第一个N-1呼叫者所在的类型 wait 阻止和第N个来电者 wait 导致他们全部释放。


3525
2018-03-09 16:16


起源



答案:


不,但你可以使用 QWaitCondition 制造这些障碍:

#include <QMutex>
#include <QWaitCondition>
#include <QSharedPointer>

// Data "pimpl" class (not to be used directly)
class BarrierData
{
public:
    BarrierData(int count) : count(count) {}

    void wait() {
        mutex.lock();
        --count;
        if (count > 0)
            condition.wait(&mutex);
        else
            condition.wakeAll();
        mutex.unlock();
    }
private:
    Q_DISABLE_COPY(BarrierData)
    int count;
    QMutex mutex;
    QWaitCondition condition;
};

class Barrier {
public:
    // Create a barrier that will wait for count threads
    Barrier(int count) : d(new BarrierData(count)) {}
    void wait() {
        d->wait();
    }

private:
    QSharedPointer<BarrierData> d;
};

用法示例代码:

class MyThread : public QThread {
public:
    MyThread(Barrier barrier, QObject *parent = 0) 
    : QThread(parent), barrier(barrier) {}
    void run() {
        qDebug() << "thread blocked";
        barrier.wait();
        qDebug() << "thread released";
    }
private:
    Barrier barrier;
};

int main(int argc, char *argv[])
{   
    ...
    Barrier barrier(5);

    for(int i=0; i < 5; ++i) {
        MyThread * thread = new MyThread(barrier);
        thread->start();
    }
    ...
}

14
2018-03-09 19:07



这是我的替代方法,但谢谢,你为我节省了一些编码。 - edA-qa mort-ora-y
非常感谢,@ alexisdm!只是一张便条,在 BarrierData 构造函数,您传递给构造函数的参数与变量具有相同的名称。 - Adri C.S.
@Adri:我认为这是故意的。它是完全合法的,可以帮助您避免发明愚蠢的惯例。 - Lennart Rolland
计数器永远不会重置或增加,因此此屏障只能工作一次。看看增强中的​​实现,似乎缺少一些东西! boost.org/doc/libs/1_40_0/boost/thread/barrier.hpp - Lennart Rolland


答案:


不,但你可以使用 QWaitCondition 制造这些障碍:

#include <QMutex>
#include <QWaitCondition>
#include <QSharedPointer>

// Data "pimpl" class (not to be used directly)
class BarrierData
{
public:
    BarrierData(int count) : count(count) {}

    void wait() {
        mutex.lock();
        --count;
        if (count > 0)
            condition.wait(&mutex);
        else
            condition.wakeAll();
        mutex.unlock();
    }
private:
    Q_DISABLE_COPY(BarrierData)
    int count;
    QMutex mutex;
    QWaitCondition condition;
};

class Barrier {
public:
    // Create a barrier that will wait for count threads
    Barrier(int count) : d(new BarrierData(count)) {}
    void wait() {
        d->wait();
    }

private:
    QSharedPointer<BarrierData> d;
};

用法示例代码:

class MyThread : public QThread {
public:
    MyThread(Barrier barrier, QObject *parent = 0) 
    : QThread(parent), barrier(barrier) {}
    void run() {
        qDebug() << "thread blocked";
        barrier.wait();
        qDebug() << "thread released";
    }
private:
    Barrier barrier;
};

int main(int argc, char *argv[])
{   
    ...
    Barrier barrier(5);

    for(int i=0; i < 5; ++i) {
        MyThread * thread = new MyThread(barrier);
        thread->start();
    }
    ...
}

14
2018-03-09 19:07



这是我的替代方法,但谢谢,你为我节省了一些编码。 - edA-qa mort-ora-y
非常感谢,@ alexisdm!只是一张便条,在 BarrierData 构造函数,您传递给构造函数的参数与变量具有相同的名称。 - Adri C.S.
@Adri:我认为这是故意的。它是完全合法的,可以帮助您避免发明愚蠢的惯例。 - Lennart Rolland
计数器永远不会重置或增加,因此此屏障只能工作一次。看看增强中的​​实现,似乎缺少一些东西! boost.org/doc/libs/1_40_0/boost/thread/barrier.hpp - Lennart Rolland