QT中多线程QWaitCondition例子解析

来源:互联网 发布:基于tcp的socket编程 编辑:程序博客网 时间:2024/05/03 15:52
#include "mainwindow.h"#include "ui_mainwindow.h"#include <QThread>#include <QDebug>#include <QMutex>#include <QWaitCondition>QMutex mutex;QWaitCondition waitCon;int number=6;int count=0;void MyThreadA::run(){    {        Qt::HANDLE h = QThread::currentThreadId();        qDebug()<<"AAAAAA begin running"<<h;        mutex.lock();        qDebug()<<"AAAAAA get mutex"<<h;        //qDebug()<<"AAAAAA release mutex and thread is waiting for exec"<<h;        bool b = waitCon.wait(&mutex);//! 先release 再等待mutex 有信号        mutex.unlock();//        ++count;//        qDebug()<<"AAAAAA count"<<count;//        mutex.unlock();        qDebug()<<" AAAAAA begin sleeping "<<h;        QThread::sleep(1);//        int i=0;//        for( i=0;i<1000000000;i++)//        {//            ;//        }        qDebug()<<" AAAAAA end sleeping "<<h;//        mutex.lock();//        --count;        qDebug()<<"AAAAAA end running"<<h;    }}void MyThreadB::run(){    //forever    {        Qt::HANDLE h = QThread::currentThreadId();        qDebug()<<"BBBBBB begin running"<<h;        mutex.lock();        qDebug()<<"BBBBBB get mutex"<<h;        //qDebug()<<"BBBBBB release mutex and thread is waiting for exec"<<h;        bool b = waitCon.wait(&mutex);        mutex.unlock();//        ++count;//        qDebug()<<"BBBBBB count"<<count;//        mutex.unlock(); //! 解锁后仍然可以正常运行        qDebug()<<" BBBBBB begin sleeping "<<h<<b;        QThread::sleep(4);//        int i=0;//        for(i=0;i<1000000000;i++)//        {//            ;//        }        qDebug()<<" BBBBBB end sleeping "<<h;//        mutex.lock();//        --count;        //mutex.unlock();        qDebug()<<"BBBBBB end running"<<h;    }}void MyThreadC::run(){    //forever    {        Qt::HANDLE h = QThread::currentThreadId();        qDebug()<<"CCCCCC begin running;"<<h;        mutex.lock();        qDebug()<<"CCCCCC get mutex"<<h;        //qDebug()<<"CCCCCC release mutex and thread is waiting for exec"<<h;        bool b = waitCon.wait(&mutex);        mutex.unlock();//        ++count;//        qDebug()<<"CCCCCC count"<<count;//        mutex.unlock();        qDebug()<<" CCCCCC begin sleeping "<<h<<b;        QThread::sleep(7);//        int i=0;//        for( i=0;i<1000000000;i++)//        {//            ;//        }        qDebug()<<" CCCCCC end sleeping "<<h;//        mutex.lock();//        --count;        //mutex.unlock();        qDebug()<<"CCCCCC end running"<<h;    }}void MainWindow::on_pushButton_2_clicked(){    Qt::HANDLE h = QThread::currentThreadId();    qDebug()<<"on_pushButton_2_clicked start  "<<h;//    mutex.lock();//    qDebug()<<"count== "<<count;//    while(count>0)//    {//        mutex.unlock();//        QThread::sleep(1);//        mutex.lock();//    }    waitCon.wakeAll();    //mutex.unlock();    //a.wait();    //b.wait();    //c.wait();    //a.run(); //单线程执行 整个程序是一个单线程       //b.run(); //单线程执行 整个程序是一个单线程       //a.terminate();       //b.terminate();       //a.wait();       //b.wait();}MainWindow::MainWindow(QWidget *parent) :    QMainWindow(parent),    ui(new Ui::MainWindow){    ui->setupUi(this);}MainWindow::~MainWindow(){    delete ui;}void MainWindow::on_pushButton_clicked(){    {        a.start();        b.start();        c.start();//! 3个线程同时启动        Qt::HANDLE h = QThread::currentThreadId();        qDebug()<<"on_pushButton_clicked start  "<<h;    }}


下面是给一个线程传递不同参数的代码:

renderthread.h:

#ifndef RENDERTHREAD_H#define RENDERTHREAD_H#include <QMutex>#include <QSize>#include <QThread>#include <QWaitCondition>//! [0]class RenderThread : public QThread{    Q_OBJECTpublic:    RenderThread(QObject *parent = 0);    ~RenderThread();    void render(QString str1,QString str2);signals:    void renderedImage(const QString &image, QString scaleFactor);protected:    void run() Q_DECL_OVERRIDE;private:    QMutex mutex;    QWaitCondition condition;    QString str1;    QString str2;    bool restart;    bool abort; //! 用于在析构的时候 退出RUN里面的循环    enum { ColormapSize = 512 };    uint colormap[ColormapSize];};//! [0]#endif // RENDERTHREAD_H


renderthread.cpp

#include "renderthread.h"#include <QtWidgets>#include <cmath>//! [0]RenderThread::RenderThread(QObject *parent)    : QThread(parent){    restart = false;    abort = false;}RenderThread::~RenderThread(){    mutex.lock();    abort = true;    //condition.wakeOne();    condition.wakeAll();    mutex.unlock();    wait();}//! [1]//! [2] -- 给线程 RenderThread 传值 同时开始让线程开始执行  -- 此为在主线程中void RenderThread::render(QString str1, QString str2){    QMutexLocker locker(&mutex);    //! 线程成员变量赋值 b    this->str1 = str1;    this->str2 = str2;    //! 线程成员变量赋值 e    if (!isRunning()) //! 若线程没有执行,则执行线程    {        Qt::HANDLE h = QThread::currentThreadId();        qDebug()<<"start(LowPriority);   "<<h;        start(LowPriority);    } else //! 若线程正在执行,则重启线程执行    {        Qt::HANDLE h = QThread::currentThreadId();        qDebug()<<"condition.wakeAll();   "<<h;        restart = true;        //condition.wakeOne();        condition.wakeAll();    }}//! [3]void RenderThread::run(){    forever {        Qt::HANDLE h = QThread::currentThreadId();        qDebug()<<"RenderThread::run()-----  "<<str1<<str2<<h; //! 只进一次//        mutex.lock();//        QSize resultSize = this->resultSize;//        double scaleFactor = this->scaleFactor;//        double centerX = this->centerX;//        double centerY = this->centerY;//        mutex.unlock();        //! 下面进行数据处理        while(1)        {            if (abort) //! 如果终止线程,直接return  {return;}            if (restart) //! 如果重启,跳出循环            {                qDebug()<<"RenderThread::run()-- restart -  "<<str1<<str2<<h;                break;            }            if (!restart) //! 发射信号 若没有外部打扰 restart,则会一直在这个里面循环            {                QString s1="aaa";                QString s2="bbb";                emit renderedImage(s1, s2);            }            //qDebug()<<"RenderThread::run()--";        }        mutex.lock();        if (!restart){condition.wait(&mutex);}//! 等到信号后,会把 mutex LOCK        restart = false;        mutex.unlock();    }}


调用方:
void MainWindow::on_pushButton_clicked(){    Qt::HANDLE h = QThread::currentThreadId();    qDebug()<<"on_pushButton_clicked   "<<h;    thread.render("1111","bbbb");}void MainWindow::on_pushButton_2_clicked(){    Qt::HANDLE h = QThread::currentThreadId();    qDebug()<<"on_pushButton_2_clicked   "<<h;    thread.render("22222","bbbbtttt");}
void RenderThread::stopThread(){    mutex.lock();    abort = true;    //condition.wakeOne();    condition.wakeAll();    mutex.unlock();    wait();    qDebug()<<"RenderThread::stopThread()()--";}void MainWindow::on_stop_clicked(){    thread.stopThread();}
---可以不停的停止线程,然后开启线程


下面是效果图:

on_pushButton_2_clicked    0x3b08condition.wakeAll();    0x3b08RenderThread::run()-- restart -   "22222" "bbbbtttt" 0x36f0RenderThread::run()-----   "22222" "bbbbtttt" 0x36f0on_pushButton_clicked    0x3b08condition.wakeAll();    0x3b08RenderThread::run()-- restart -   "1111" "bbbb" 0x36f0RenderThread::run()-----   "1111" "bbbb" 0x36f0on_pushButton_2_clicked    0x3b08condition.wakeAll();    0x3b08RenderThread::run()-- restart -   "22222" "bbbbtttt" 0x36f0RenderThread::run()-----   "22222" "bbbbtttt" 0x36f0





0 0
原创粉丝点击