Qt 线程同步之 QWaitCondition
来源:互联网 发布:dnf淘宝买金币安全吗 编辑:程序博客网 时间:2024/05/21 04:22
简述
本博用 QWaitCondition 实现了线程同步中的“生产者-消费者”模式。
- 简述
- 详述
- 效果图
- 关键知识
- 源码
- 类的创建
- 类的使用
- 源码下载
详述
- 生产者线程生产数字,存放在 vector 中。消费者线程消耗数字。
- 生产者线程先检测 vector 中的数字的总个数是否超出规定的限制(即代码中的 NUMBER_SIZE),超过限制则生产者线程阻塞,直到消费者线程发出 numberNotFull 条件才会进行下一步。接下来消费者线程会产生一个随机数添加到 vector 尾部,并发送numberNotEmpty 条件。
- 消费者线程先检测 vector 中的数字个数是否为 0,为0的话,消费者线程阻塞,直到生产者线程发出 numberNotEmpty 条件才会进行下一步。接下来消费者线程取出 vector 中的第一个元素,发送给主线程。并发送 numberNotFull 条件。
效果图
关键知识
理解 QWaitCondition 的重点在于理解其 wait 函数;此处一定要详细地看文档,摘录如下:
函数原型:
bool QWaitCondition::wait(QMutex *lockedMutex, unsigned long time = ULONG_MAX)
释义:
Releases the lockedMutex and waits on the wait condition. The lockedMutex must be initially locked by the calling thread. If lockedMutex is not in a locked state, the behavior is undefined. If lockedMutex is a recursive mutex, this function returns immediately. The lockedMutex will be unlocked, and the calling thread will block until either of these conditions is met:
Another thread signals it using wakeOne() or wakeAll(). This function will return true in this case.
time milliseconds has elapsed. If time is ULONG_MAX (the default), then the wait will never timeout (the event must be signalled). This function will return false if the wait timed out.
The lockedMutex will be returned to the same locked state. This function is provided to allow the atomic transition from the locked state to the wait state.
源码
类的创建
testThread.h
#pragma once#include <QThread>class ThreadConsumer : public QThread{ Q_OBJECTpublic: ThreadConsumer(QObject *parent); ~ThreadConsumer(); void run() Q_DECL_OVERRIDE; bool threadStatus(); void setThreadStatus(bool status);signals: void sendToMainWindow(const int);private: bool m_threadStatus;};class ThreadProducer : public QThread{ Q_OBJECTpublic: ThreadProducer(QObject *parent); ~ThreadProducer(); void run() Q_DECL_OVERRIDE; bool threadStatus(); void setThreadStatus(bool status);private: bool m_threadStatus;};
testThread.cpp
#include "testThread.h"#include<QWaitCondition>#include <QMutex>#include <QVector>#include <QTime>QWaitCondition numberNotFull;QWaitCondition numberNotEmpty;QMutex mutex;QVector<int> vectInt;const int NUMBER_SIZE = 3;int generateRandomInteger(int min, int max);ThreadConsumer::ThreadConsumer(QObject *parent) : QThread(parent){ m_threadStatus = true;}ThreadConsumer::~ThreadConsumer(){}void ThreadConsumer::run() { while (m_threadStatus) { mutex.lock(); if (vectInt.isEmpty()) numberNotEmpty.wait(&mutex); emit sendToMainWindow(vectInt.value(0)); vectInt.pop_front(); mutex.unlock(); numberNotFull.wakeAll(); }}void ThreadConsumer::setThreadStatus(bool status){ m_threadStatus = status;}bool ThreadConsumer::threadStatus(){ return m_threadStatus;}//===================================================================//类的分界线ThreadProducer::ThreadProducer(QObject *parent) : QThread(parent){ m_threadStatus = true;}ThreadProducer::~ThreadProducer(){}void ThreadProducer::run(){ while (m_threadStatus) { mutex.lock(); if (vectInt.size() > NUMBER_SIZE) numberNotFull.wait(&mutex); mutex.unlock(); int number = generateRandomInteger(0, 1000); mutex.lock(); vectInt.push_back(number); mutex.unlock(); numberNotEmpty.wakeAll(); sleep(1);//避免频繁刷新界面 }}void ThreadProducer::setThreadStatus(bool status){ m_threadStatus = status;}bool ThreadProducer::threadStatus(){ return m_threadStatus;}// 生成随机数 min:随机数的最小值,max:随机数的最大值int generateRandomInteger(int min, int max){ Q_ASSERT(min < max); // 加入随机种子。种子是当前时间距离0点0分0秒的秒数。 // 每次启动程序,只添加一次种子,以做到数字真正随机。 static bool seedStatus; if (!seedStatus) { qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime())); seedStatus = true; } int nRandom = qrand() % (max - min); nRandom = min + nRandom; return nRandom;}
类的使用
main.cpp
#include "testApp.h"#include <QtWidgets/QApplication>int main(int argc, char *argv[]){ QApplication a(argc, argv); testApp w; w.show(); return a.exec();}
testApp.h
#pragma once#include <QtWidgets/QMainWindow>#include "ui_testApp.h"class ThreadConsumer;class ThreadProducer;class testApp : public QMainWindow{ Q_OBJECTpublic: testApp(QWidget *parent = Q_NULLPTR); ~testApp();protected slots: void on_btnStart_clicked(); void handleResult(const int);private: Ui::testAppClass ui; ThreadConsumer* thdConsumer; ThreadProducer* thdProducer;};
testApp.cpp
#include "testApp.h"#include "testThread.h"testApp::testApp(QWidget *parent) : QMainWindow(parent){ ui.setupUi(this); setWindowTitle(QStringLiteral("线程同步")); thdConsumer = new ThreadConsumer(this); thdProducer = new ThreadProducer(this); connect(thdConsumer, &QThread::finished, thdConsumer, &QObject::deleteLater); connect(thdConsumer, &ThreadConsumer::sendToMainWindow, this, &testApp::handleResult);}void testApp::on_btnStart_clicked(){ thdConsumer->setThreadStatus(true); thdConsumer->start(); thdProducer->setThreadStatus(true); thdProducer->start();}void testApp::handleResult(const int number){ ui.lineEdit->setText(QString::number(number));}testApp::~testApp(){ thdConsumer->setThreadStatus(false); thdConsumer->quit(); thdConsumer->wait(); thdProducer->setThreadStatus(false); thdProducer->quit(); thdProducer->wait();}
testApp.ui
源码下载
QWaitCondition-源码下载-【站内链接】
- Qt 线程同步之 QWaitCondition
- Qt之线程同步(生产者消费者模式 - QWaitCondition)
- QT之使用 QWaitCondition 同步线程小例子
- Qt 线程同步(QMutex、QWaitCondition、QSemaphore)
- QSemaphore、QWaitCondition实现线程同步
- 【Qt多线程之线程的等待和唤醒】QWaitCondition
- Qt之线程同步
- Qt之线程同步
- Qt之线程同步
- qt线程同步之信号量
- 一个Qt线程的例子,用于说明QWaitCondition的作用
- Qt随笔之Qt线程同步
- QT——QWaitCondition
- Qt的QWaitCondition
- Qt的QWaitCondition
- Qt QWaitCondition的应用
- Qt的QWaitCondition
- Qt的QWaitCondition
- Servlet基础
- 二叉树遍历——转载于网易博客summer
- phpdoc
- 2017-09-10 LeetCode_020 Valid Parentheses
- java volatile关键字的用法
- Qt 线程同步之 QWaitCondition
- HDU 6197 array array array(最长不下降子序列)
- 递归汉诺塔
- 利用nat123实现公网访问内网
- PHP 常量
- restful
- 尺取法
- QMainWindow布局
- 无法注入XXXMapper