QThread只有run函数在新线程中,其他所有函数都在QThread生成的线程中
如果QThread是在具有ui的线程中生成的,则QThread中的所有其他非run函数都与ui线程相同。 因此,请尽量不要对QThread继承类的其他函数执行耗时的操作。 请确保run函数中存在所有耗时的操作。
在UI线程下调用QThread的非run函数实际上应该使用start函数,而不是直接调用run函数。 和执行普通函数没有区别。 此时,必须对具有QThread的变量进行更改,如果该变量也用于run函数,则需要注意锁定的问题,因为该变量可能在几毫秒前刚刚在run中调用
安全退出线程:
3359 blog.csdn.net/czyt 1988/article/details/6441443
1.工作线程
每个程序启动后拥有的第一个线程称为主线程,也就是GUI线程。 QT中的所有组件类和一些相关类仅在GUI线程上运行,并且是唯一可以执行GUI相关操作的线程。 不适用于子线程。 子线程是工作线程,主要处理从GUI线程中移除的工作。 每个线程都有自己的堆栈
2.多线程简介
QT线程类包括:
QThread提供跨平台多线程解决方案
QThreadStorage提供逐线程数据存储
QMutex提供相互排斥的锁定或排斥的量
QMutexLocker是一个辅助类,可自动锁定和解锁QMutex
QReadWriterLock有一个锁,可以同时读取操作
QReadLocker和QWriteLocker会自动锁定和解锁QReadWriteLock
QSemaphore提供整数信号量,是互斥量的泛化
QWaitCondition提供了一种让线程暂停直到被另一个线程唤醒的方法
3.线程优先级
4.线程的执行
void run ()线程卷函数,定义线程的功能
启动void start ()函数并将线程项地址设置为run函数
5.线程的退出
void quit () )
退出线程并返回0时成功,相当于qthread3360exit(0)
void exit (交叉代码=0) : thread退出事件loop并从exec返回。 exec的返回值是返回代码。 通常,返回代码=0表示成功,其他值表示失败
voidterminate(:强制退出线程,不保证数据完整性和资源释放
打开设置启用(bool enabled=true ) :terminate ()
6.线程的等待
布尔等待(unsigned long time=ulong _ max ) :线程被阻止并等待time毫秒。 线程结束后,等待会返回。 wit函数解决了对多线程执行时间的依赖
统一长secs (void sleep )。
唯一长消息(void msleep )。
统一长使用(void usleep )。
7.线程的状态
is运行(:线程是否正在运行?
isfinished () :线程是否已退出
8 .线程和事件循环
q调用QThread中run () (默认实现为exec ) )以创建QEventLoop对象。 QEventLoop对象处理线程中的事件,每个线程都有自己的事件队列。 exec ) )在其中循环遍历事件队列,调用QThread的quit ) )或exit ) )方法使线程终止,而terminate ) )不终止线程terminate ) )退出线程太粗暴,无法释放资源,独占锁定也无法解除。
http://www.Sina.com/http://www.Sina.com /
关键资源:一次只能访问一个线程的资源
线程间互斥:多个线程必须同时访问关键资源
线程锁保证了临界资源的安全性。 每个临界资源通常需要线程锁来保护。
线程死锁:由于线程之间正在等待关键资源,因此无法继续彼此运行。
发生死锁的条件:
答、系统存在多种临界资源,且不能切断临界资源
b、线程需要多个关键资源才能继续运行
避免死锁:
a .为使用的每个临界资源分配唯一的序列号
b、为与每个关键资源对应的线程锁分配适当的序列号
c、系统中各线程按严格增长的顺序要求临界资源
QMutex,QReadWriteLock,QSe
maphore, QWaitCondition 提供了线程同步的手段。使用线程的主要想法是希望它们可以尽可能并发执行,而一些关键点上线程之间需要停止或等待。例如,假如两个线程试图同时访问同一个全局变量,结果可能不如所愿。2.互斥量QMutex
QMutex 提供相互排斥的锁,或互斥量。在一个时刻至多一个线程拥有mutex,假如一个线程试图访问已经被锁定的mutex,那么线程将休眠,直到拥有mutex的线程对此mutex解锁。QMutex常用来保护共享数据访问。QMutex类所以成员函数是线程安全的。
头文件声明: #include <QMutex>
互斥量声明: QMutex m_Mutex;
互斥量加锁: m_Mutex.lock();
互斥量解锁: m_Mutex.unlock();
如果对没有加锁的互斥量进行解锁,结果是未定义的。互斥量的加锁和解锁必须在同一线程中成对出现。
QMutex ( RecursionMode mode = NonRecursive )
QMutex有两种模式:Recursive, NonRecursive
A、Recursive
一个线程可以对mutex多次lock,直到相应次数的unlock调用后,mutex才真正被解锁。
B、NonRecursive
默认模式,mutex只能被lock一次。
如果使用了Mutex.lock()而没有对应的使用Mutex.unlcok()的话就会造成死锁,其他的线程将永远也得不到接触Mutex锁住的共享资源的机会
bool tryLock();
如果当前其他线程已对该mutex加锁,则该调用会立即返回,而不被阻塞。
bool tryLock(int timeout);
如果当前其他线程已对该mutex加锁,则该调用会等待一段时间,直到超时
子类化QThread方式启动线程Demo
mythread.h
#ifndef MYTHREAD_H#define MYTHREAD_H#include <QThread>#include <QMutex>class MyThread : public QThread{ Q_OBJECTpublic: explicit MyThread(QObject *parent = 0); void startThread(); //开启线程 void stop(); //停止线程protected: void run(); //线程主执行函数private: volatile bool stopped; //线程停止位 QMutex m_mutex; //互斥锁};#endif // MYTHREAD_Hmythread.cpp
#include "mythread.h"#include <QDebug>MyThread::MyThread(QObject *parent) : QThread(parent){ stopped = false;}void MyThread::run(){ qreal i = 0; while (!stopped) { qDebug() << QString("in MyThread: %1").arg(i); msleep(1000); i++; }}void MyThread::startThread(){ m_mutex.lock(); stopped = false; m_mutex.unlock(); start();}void MyThread::stop(){ m_mutex.lock(); stopped = true; m_mutex.unlock();}