首页 > 编程知识 正文

qt多线程创建多个不同的线程(qt socket 多线程)

时间:2023-05-04 14:08:59 阅读:75733 作者:629

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_H

mythread.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();}

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。