zoukankan      html  css  js  c++  java
  • Qt学习笔记 线程(一)

    Qt中的线程是与平台无关的

    QThread 提供了创建一个新线程的方法

    新建一个线程,继承QThread并重写它的run()当调用 start()函数时会调用重载的run()函数

    例:

    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    #include <QThread>
    
    class MyThread : public QThread
    {
        Q_OBJECT
    public:
        bool stop ;
        explicit MyThread(QObject *parent = 0);
        void run();
    signals:
    
    public slots:
    
    };
    #endif // MYTHREAD_H
    #include "mythread.h"
    #include<QDebug>
    MyThread::MyThread(QObject *parent) :
        QThread(parent)
    {
        stop = false;
    }
    void MyThread::run()
    {
        for(int i=0;i<1000;i++)
        {
            if(stop)break;
            qDebug()<<i;
            QThread::sleep(1);
        }
    }
    #include <QCoreApplication>
    #include "myobject.h"
    #include <QThread>
    #include<QDebug>
    #include "mythread.h"
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        MyThread myThread;
        myThread.start();
        QThread::sleep(10);
        myThread.stop=true;
        return a.exec();
    }

    看一下Qt中包含的线程类:

    QThread 所有线程的基类,提供了创建一个线程的方法

    QThreadStorge 提供一逐线程数据存储

    QMutex 提供相互排斥的锁,或互斥量

    QMutexLocker 可以自动对QMutex加锁与解锁

    QReadWirterLock 提供了一个可以同时读操作的锁

    QreadLocker与QwriteLocker可以自动对QReadWriteLock加锁与解锁 

    QSempHore提供了一个整形信号量,是互斥的泛化

    QWaitCondition提供了一种方法,使线程可以在被另外线程唤醒之前一直休眠

    线程的同步

    QMutex 提供相互排斥的锁,或互斥量

    QMetex提供了lock和Unlock函数,如果 一个已经锁定 这个互斥量,只有这个线程unlock后其它线程才可以

    访问

    把上边的例子做一下修改,只是为了方便大家理解,这个例子没什么作用

    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    #include <QThread>
    
    class QMutex;
    class MyThread : public QThread
    {
        Q_OBJECT
    private:
        QMutex qm;
        bool stop;
    public:
        explicit MyThread(QObject *parent = 0);
        void run();
        void SetFlg(bool flg);
    signals:
    public slots:
    
    };
    #endif // MYTHREAD_H
    #include "mythread.h"
    #include<QDebug>
    #include<QMutex>
    MyThread::MyThread(QObject *parent) :
        QThread(parent)
    {
        stop = false;
    }
    void MyThread::SetFlg(bool flg)
    {
        qm.lock();
        stop=flg;
        qm.unlock();
    }
    
    void MyThread::run()
    {
        for(int i=0;i<1000;i++)
        {
            qm.lock();
            if(stop)
            {
                qm.unlock();
                break;
            }
            qDebug()<<i;
            QThread::sleep(1);
            qm.unlock();
        }
    }
    #include <QCoreApplication>
    #include "myobject.h"
    #include <QThread>
    #include<QDebug>
    #include "mythread.h"
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        MyThread myThread;
        myThread.start();
        QThread::sleep(10);
        myThread.SetFlg(true);
        return a.exec();
    }

    使用QMutex时要小心因为如果 lock()后没有unlock()会导致死锁别的线程就

    永远也不能访问资源了

    Qt提供了QMutexLocker来解决这个问题

    修改我们的app文件

    #include "mythread.h"
    #include<QDebug>
    #include<QMutex>
    #include<QMutexLocker>
    MyThread::MyThread(QObject *parent) :
        QThread(parent)
    {
        stop = false;
    }
    void MyThread::SetFlg(bool flg)
    {
        QMutexLocker locker(&qm);
        stop=flg;
    }
    
    void MyThread::run()
    {
        QMutexLocker locker(&qm);
        for(int i=0;i<1000;i++)
        {
            if(stop)
            {
                break;
            }
            qDebug()<<i;
            QThread::sleep(1);
    
        }
    }

    QMutexLocker会自己unluck

    QMutexLocker也提供了一个mutex()成员函数返回QMutexLocker操作的互斥量。对于需要访问互斥量是十分有用的,比如QWaitCondition::wait()。

    QReadWirterLock 

    用mutext进行线程同步有一个问题某个时刻只许一个线程访问资源如果同时有多个线程对共享资源进行访问,

    同时有写操作线程那么这种情况下采用mutex就会成为程序的瓶颈。使用QReadWriteLock来实现多线程

    读操作,一个线程写操作,写线程执行时会阻塞所有的读线程,而读线程运行不需要进行同步

    QReadWriteLock lock;
    
    void ReaderThread::run()
    {
        ...
        lock.lockForRead();
        read_file();
        lock.unlock();
        ...
    }
    
    void WriterThread::run()
    {
        ...
        lock.lockForWrite();
        write_file();
        lock.unlock();
        ...
    }

    QreadLocker和QWriteLocker类是对QReadWirterLock 的简化

    它们会自动unluck();

    QReadWriteLock lock;
    
    QByteArray readData()
    {
        QReadLocker locker(&lock);
        ...
        return data;
    }

    相当于QReadWirterLock 的写法如下

    QReadWriteLock lock;
    
    QByteArray readData()
    {
        lock.lockForRead();
        ...
        lock.unlock();
        return data;
    }
  • 相关阅读:
    Wijmo 更优美的jQuery UI部件集:在对Wijmo GridView进行排序或者过滤时保留选择
    Wijmo 更优美的jQuery UI部件集:活动日历控件(Event Calendar)
    Wijmo 更优美的jQuery UI部件集:导出Wijmo的GridView到Excel
    Wijmo 更优美的jQuery UI部件集:服务器端Grid魔法
    Wijmo 更优美的jQuery UI部件集:在安全站点使用Wijmo控件
    Wijmo 更优美的jQuery UI部件集:复合图表(CompositeChart)
    Wijmo 更优美的jQuery UI部件集:C1 Wijmo Grids 更多惊喜
    Hello Metro:Windows 8下首个App
    Wijmo 更优美的jQuery UI部件集:运行时处理Wijmo GridView数据操作
    Wijmo 更优美的jQuery UI部件集:自定义 C1WijMenu
  • 原文地址:https://www.cnblogs.com/li-peng/p/3653781.html
Copyright © 2011-2022 走看看