Qt学习笔记 线程(一)

简介: Qt中的线程是与平台无关的 QThread 提供了创建一个新线程的方法 新建一个线程,继承QThread并重写它的run()当调用 start()函数时会调用重载的run()函数 例: #ifndef MYTHREAD_H #define MYTHREAD_H #include ...

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;
}

 

 

 

目录
相关文章
|
24天前
|
编解码 数据安全/隐私保护 计算机视觉
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
如何使用OpenCV进行同步和异步操作来打开海康摄像头,并提供了相关的代码示例。
59 1
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
|
2月前
|
网络协议 安全
QT多线程
本文详细介绍了在Qt中如何正确使用QThread以及信号槽跨线程的使用方式,包括线程的正确退出方法和QObject在不同线程中创建子对象时可能遇到的问题。同时,文章还提供了相关博客和资料的链接,用于进一步学习和参考。
|
2月前
|
数据库 数据库管理
qt对sqlite数据库多线程的操作
本文总结了在Qt中进行SQLite数据库多线程操作时应注意的四个关键问题,包括数据库驱动加载、加锁、数据库的打开与关闭,以及QsqlQuery变量的使用。
101 1
|
24天前
FFmpeg学习笔记(二):多线程rtsp推流和ffplay拉流操作,并储存为多路avi格式的视频
这篇博客主要介绍了如何使用FFmpeg进行多线程RTSP推流和ffplay拉流操作,以及如何将视频流保存为多路AVI格式的视频文件。
136 0
|
3月前
|
调度
多线程学习笔记
这篇文章是多线程学习笔记,涵盖了线程与进程的概念、多线程实现方式、线程状态、线程同步与不安全示例、死锁问题以及生产者与消费者问题等多线程编程的关键知识点。
多线程学习笔记
|
2月前
自己动手写QT多线程demo
本文是作者关于如何编写Qt多线程demo的教程,介绍了如何实现多线程功能,包括可暂停和继续的功能。文章提供了部分示例代码,展示了如何创建线程类、启动和管理线程,以及线程间的通信。同时,还提供了相关参考资料和免费下载链接。
|
3月前
【Qt 学习笔记】Qt窗口 | 标准对话框 | 消息对话框QMessageBox
【Qt 学习笔记】Qt窗口 | 标准对话框 | 消息对话框QMessageBox
510 4
【Qt 学习笔记】Qt窗口 | 标准对话框 | 消息对话框QMessageBox
|
3月前
|
开发者
【Qt 学习笔记】Qt系统相关 | Qt事件 | 事件的介绍及基本概念
【Qt 学习笔记】Qt系统相关 | Qt事件 | 事件的介绍及基本概念
183 4
|
3月前
【Qt 学习笔记】Qt窗口 | 标准对话框 | 文件对话框QFileDialog
【Qt 学习笔记】Qt窗口 | 标准对话框 | 文件对话框QFileDialog
616 4
|
3月前
|
数据安全/隐私保护
【Qt 学习笔记】Qt窗口 | 对话框 | 模态与非模态对话框的创建
【Qt 学习笔记】Qt窗口 | 对话框 | 模态与非模态对话框的创建
320 4