Qt多线程学习之路(1)
本文2018年记录,2019929尝试使用B站文章作记录博客
本文记录Qt/C++多线程学习中不断踩到的坑,谨作个人学习备份记录,如有不当请指正
首发于个人博客dksoft.site
学习线程前需要了解两个术语:
§ 可重入的(Reentrant):如果多个线程可以在同一时刻调用一个类的所有函数,并且保证每一次函数调用都引用一个唯一的数据,就称这个类是可重入的(Reentrant means that all the functions in the referenced class can be called simultaneously by multiple threads, provided that each invocation of the functions reference unique data.)。大多数 C++ 类都是可重入的。类似的,一个函数被称为可重入的,如果该函数允许多个线程在同一时刻调用,而每一次的调用都只能使用其独有的数据。全局变量就不是函数独有的数据,而是共享的。换句话说,这意味着类或者函数的使用者必须使用某种额外的机制(比如锁)来控制对对象的实例或共享数据的序列化访问。
§ 线程安全(Thread-safe):如果多个线程可以在同一时刻调用一个类的所有函数,即使每一次函数调用都引用一个共享的数据,就说这个类是线程安全的(Threadsafe means that all the functions in the referenced class can be called simultaneously by multiple threads even when each invocation references shared data.)。如果多个线程可以在同一时刻访问函数的共享数据,就称这个函数是线程安全的。
§ Qt::DirectConnection:直接连接意味着槽函数将在信号发出的线程直接调用
§ Qt::QueuedConnection:队列连接意味着向接受者所在线程发送一个事件,该线程的事件循环将获得这个事件,然后之后的某个时刻调用槽函数
§ Qt::BlockingQueuedConnection:阻塞的队列连接就像队列连接,但是发送者线程将会阻塞,直到接受者所在线程的事件循环获得这个事件,槽函数被调用之后,函数才会返回
§ Qt::AutoConnection:自动连接(默认)意味着如果接受者所在线程就是当前线程,则使用直接连接;否则将使用队列连接
运用线程容易踩的坑:
1、线程及线程管理者都存在依附性,线程管理者(Thread对象)依附于创建它(创建对象)的线程。所以例如,子线程类中存在槽函数,主线程创建线程管理者对象及发出信号。连接
槽函数和信号后执行发现,本槽采用队列连接,信号在主线程中发送,接收者槽函数也在主线程中。即本例槽函数实际上在主线程中执行,如本槽运行耗时操作,将阻塞主线程。
2、使用moveToThread可改变线程依附性,如上例中槽函数实际运行在主函数中,此时使用moveToThread(线程管理者);讲线程依附性移至子线程中,再执行耗时操作讲不会阻塞主线程。注意:子线程类想要接受信号必须在run()中写exec();开启子线程,否则连接信号槽将无效。
