qt_线程

本文详细介绍了Qt中的线程概念,包括GUI线程与次要线程,线程同步机制如QMutex、QReadWriteLock和QSemaphore等。同时提到了线程安全和事件驱动对象的限制。此外,还探讨了QtConcurrent提供的多线程高级API,如run()函数和QFutureWatcher。最后,简单介绍了QThread的start()、quit()等关键方法。
摘要由CSDN通过智能技术生成

线程

线程分为gui线程(主线程)和次要线程,涉及gui的必须在主线程

线程的同步

两个线程可以同时访问一个对象,试想如果一个对象同时执行两种方法则可能出错
QMutex 是强制执行互斥的基本类。一个线程锁定一个互斥量(mutex),以获得共享资源的访问权限。如果另一个线程试图锁定互斥量,而互斥量已被锁定,这时,它将进入睡眠状态,直到第一个线程完成其任务并解锁互斥量。

QReadWriteLock 类似于 QMutex,除了它区分了“读”和“写”的访问。当一个数据块没有被写入,多线程对他同时进行读取是安全的。一个 QMutex 迫使轮流读取共享数据,而 QReadWriteLock 允许同时读取,从而提高并行性。
QSemaphore 是 QMutex 的一个推广,可以保护一定数量相同的资源。相比之下,一个 QMutex 只能保护一个资源
QWaitCondition 同步线程,不通过执行互斥,而通过提供一个条件变量。其它原语使线程等待,直到资源被解锁
QMutexLocker、QReadLockerQWriteLocker 是便利类,使其更易于使用 QMutex 和QReadWriteLock 。当他们被构建时,就会锁定资源;当被销毁时,就会自动解锁。设计他们是为了简化使用 QMutex 和 QReadWriteLock 的代码,从而减少资源被永久锁定的可能性。

线程安全的可重入类
注意点:
1.事件的驱动对象只能被使用在单线程中,也就是不能在此线程中引用别的线程的socket或者定时器之类的
2.gui类是不可重入的,只能放在主线程中

class Counter
{
   
public:
    Counter() {
    n = 0; }

    void increment() {
    QMutexLocker locker(&mutex); ++n; }//局部变量locker销毁时mutex被释放相当于unlock了
    void decrement() {
    QMutexLocker locker(&mutex); --n; }
    int value() const {
    QMutexLocker locker(&mutex); return n; }

private:
    mutable QMutex mutex;//由于const,所以加mutable,可修改
    int n;
};

**QObject::moveToThread()**函数改变一个对象和它的孩子的线程所属性。
从另一个线程(不是该QObject对象所属的线程)对该QObject对象调用delete方法是不安全的,除非你能保证该对象在那个时刻不处理事件,使用QObejct::deleteLater()更好。一个DeferredDelete类型的事件将被提交(posted),而该对象的线程的事件循环最终会处理这个事件。默认情况下,拥有一个QObject的线程就是创建QObject的那个线程,而不是QObject::moveToThread()被调用后的。
QCoreApplication::postEvent(),你可以在任何时刻给任何线程中的任何对象发送事件,这些事件将自动被分发到该对象所被创建的线程事件循环中。
**QCoreApplication::sendEvent()**不同于postEvent())只能将事件分发到和该函数调用者相同的线程中的对象。
可以在QThread::run()的实现中安全地发射信号,因为信号发射是线程安全的或者必须用一个mutex保护对该QObject子类的内部数据的所有访问

QtConcurrent

该QtConcurrent命名空间提供高层次的API,使人们可以编写多线程程序,而无需使用低级线程原语。
Header: #include
qmake: QT += concurrent

/*
*QStringList lowerCaseStrings = QtConcurrent::blockingFiltered(strlist, allLowerCase);//返回序列
* QtConcurrent::blockingFilter(strlist, allLowerCase);//直接修改
*/
bool allLowerCase(const QString &str)
{
   
    return str.toLower()==str;
}
void addToDictionary(QString &dictionary, const QString &string)
{
   
     dictionary.append(string);
}
GuiTest::GuiTest(QWidget *parent)
    : QMainWindow(parent)
{
   
    QStringList strlist;
    strlist<<"zylg1"<<"zylg2"<<"123"<<"ZYLG"<<"Zylg";
    foreach(QString str ,strlist)cout<<str<<"\t";cout<<endl;
    QStringList lowerCaseStrings = QtConcurrent::blockingFiltered(strlist, allLowerCase);//返回序列
    QFuture<QString> dictionary = QtConcurrent::filteredReduced(strlist, allLowerCase, addToDictionary);
    QtConcurrent::blockingFilter(strlist, allLowerCase);//直接修改
    foreach(QString str ,strlist)cout<<str<<"\t";cout<<endl;
    foreach(QString str ,lowerCaseStrings)cout<<str<<"\t";cout<<endl;
    foreach(QString str ,dictionary)cout<<str<<"\t";cout<<endl;
}
/*
 * result:
 * zylg1	zylg2	123	ZYLG	Zylg	
 * zylg1	zylg2	123	
 * zylg1	zylg2	123	
 * zylg1zylg2123	
*/
QImage scaled(const QImage &image)
{
   
    return image.scaled(100, 100);
}

QList<QImage> images = ...;
QFuture<QImage> thumbnails = QtConcurrent::mapped(images, scaled);
//void QtConcurrent::blockingMap(Iterator begin, Iterator end, MapFunctor function)
//QList<int> ints = QtConcurrent::blockingMapped<QList<int> >(beginIterator, endIterator, fn);
#include<QTextStream>
#include<QtConcurrent>
#
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值