Qt QWaitCondition 使用

/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore>

#include <stdio.h>
#include <stdlib.h>
#include <QTimer>
#include <QObject>
//! [0]
const int DataSize = 100000;

const int BufferSize = 8192;
char buffer[BufferSize];

QWaitCondition bufferNotEmpty;
QWaitCondition bufferNotFull;
QMutex mutex;
int numUsedBytes = 0;
//! [0]

//! [1]
class Producer : public QThread
//! [1] //! [2]
{
public:
    Producer(QObject *parent = NULL) : QThread(parent)
    {
    }

    void run() override
    {
        for (int i = 0; i < DataSize; ++i) {
            mutex.lock();
            if (numUsedBytes == BufferSize)
                bufferNotFull.wait(&mutex);
            mutex.unlock();

            buffer[i % BufferSize] = "ACGT"[QRandomGenerator::global()->bounded(4)];

            mutex.lock();
            ++numUsedBytes;
            bufferNotEmpty.wakeAll();
            mutex.unlock();
        }
    }
};
//! [2]

//! [3]
class Consumer : public QThread
//! [3] //! [4]
{
    Q_OBJECT
public:
    Consumer(QObject *parent = NULL) : QThread(parent)
    {
    }

    void run() override
    {
        for (int i = 0; i < DataSize; ++i) {
            mutex.lock();
            if (numUsedBytes == 0)
                bufferNotEmpty.wait(&mutex);
            mutex.unlock();

            fprintf(stderr, "%c", buffer[i % BufferSize]);

            mutex.lock();
            --numUsedBytes;
            bufferNotFull.wakeAll();
            mutex.unlock();
        }
        fprintf(stderr, "\n");
    }

signals:
    void stringConsumed(const QString &text);
};
//! [4]


class App;
class Api;
QWaitCondition g_doCond;
QMutex g_mutexApp;
class App:public QObject
{
    Q_OBJECT
public:
    App(){
        m_api = nullptr;
    }

    ~App(){

    }

    void init(Api* api) {
        m_api = api;
    }

public slots:
    void autoRun() {
        qDebug() << "entered app autoRun";
        QMetaObject::invokeMethod((QObject*)m_api, "doSomething", Qt::QueuedConnection);
        g_mutexApp.lock();
        qDebug() << "auto run done, lock///";
        g_doCond.wait(&g_mutexApp);
        qDebug() << "auto run done, unlock///";
        g_mutexApp.unlock();
        qDebug() << "auto run done, wake up///";
    }

private:
    Api *m_api;
};


QWaitCondition g_doneCond2;
QMutex g_mutexApi2;
class Api:public QObject
{
    Q_OBJECT
public:

    Api(){

    }

    ~Api(){

    }
public slots:
    void doSomething(){
        qDebug() << "do ing";
        QTimer::singleShot(2000, this, &Api::onDone);
    }

    void onDone(){
        qDebug() << "done";
        g_mutexApp.lock();
        g_doCond.wakeAll();
        g_mutexApp.unlock();
    }
};


void test()
{
    qDebug() << __FUNCTION__" thread id=" << QThread::currentThreadId();
    QThread *threadApp = new QThread();
    QThread *threadApi = new QThread();
    App *app = new App;
    Api *api = new Api;
    app->moveToThread(threadApp);
    api->moveToThread(threadApi);
    threadApi->start();
    threadApp->start();
    app->init(api);
    qDebug() << "start app";
    QMetaObject::invokeMethod((QObject*)app, "autoRun", Qt::QueuedConnection);
    qDebug() << "test app end.";

    threadApp->wait();
    threadApi->wait();
    threadApp->deleteLater();
    threadApi->deleteLater();
    app->deleteLater();
    api->deleteLater();
}


//! [5]
int main(int argc, char *argv[])
//! [5] //! [6]
{

    QCoreApplication app(argc, argv);
    /*
    Producer producer;
    Consumer consumer;
    producer.start();
    consumer.start();
    producer.wait();
    consumer.wait();
    */

    test();

    return   app.exec();
}
//! [6]

#include "waitconditions.moc"

Sleep 使用QWaitCondition替换,app 使用 api 实现业务。 api 干活开始,app 线程被阻塞,api 干完后唤醒 app 所在线程。
避免 app sleep 循环占用cpu。

note: mutex 的使用, invkoe 的连接方式, 函数使用 slot 函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值