1.多线程的理解
在操作系统中线程和进程划分。
操作系统可以同时执行多个任务,每个任务就是进程;进程可以同时执行多个任务,每个任务就是线程。
线程之间相互独立,抢占式执行。对于单核CPU来说同一时刻只能有一个线程执行,一个进程执行。
但是由于CPU不断在这些进程间轮换执行,速度相对人的反应很快,不容易察觉。
既然这样,为什么要使用多线程呢?
a.对于多核cpu,多线程程序充分利用硬件优势
b.对于单核cpu,由于线程上下文的切换会降低整体运行效率。但是为了防止执行耗时操作时界面假死,我们必须把耗时操作单独放在线程中后台执行,防止阻塞主线程无法刷新窗口。
我们来看一下程序的阻塞和非阻塞
这里主要说对于线程之间的公共资源,同时只能由一个线程操作,在此期间其他线程访问将会被挂起直到上一次访问结束,同样客户端执行界面刷新的主线程也会挂起。
非阻塞指的是,一个线程的操作不会阻塞其他线程对事件的接受和处理。
同步和异步
这里说的执行一个操作必须等待执行完成,下面的逻辑才会继续执行,是为同步执行代码
对函数调用后,不会等待执行结果,继续执行下面的代码,是为异步执行。
2.线程使用
QT中多线程得两种处理方法
使用线程在程序执行长时间操作得时候弹出进度条
使用线程可以把占据时间长得程序中任务放到后台去处理
其中一种是继承QThread得run函数,另外一种是把一个继承于QObject得类转移到一个Thread里。
1.继承QThread
QThread继承类只有run函数是在新线程里跑的,其他函数在创建QThread线程中运行
新建一个线程类ExportThread:QThread ,把耗时操作放在其中run函数中
2.把一个继承于QObject的类转移到一个Thread里
创建一个继承自QObject类得类对象object,使用object.moveToThread(QThread *);
3.线程类中得槽函数在哪个线程中执行得问题
对于方法1中,槽函数在创建线程类对象得线程(一般是主线程)中执行
对于方法2中,槽函数在次线程中执行,通过信号槽调用,直接调用则都在调用线程中执行,
所以要把耗时操作放在槽函数中,外面信号触发,
具体需要参考,connect函数中表示连接方式得参数
如下:
同步调用:信号发出后,当前线程等待槽函数执行完毕才能执行剩余代码。
异步调用:信号发出后,立即执行剩余逻辑,不关心槽函数什么时候执行。
AutoConnection 信号和槽同一线程时,直接联,不同线程时,队列联
DirectConnection 直接联,在主线程中执行,同步调用,不依赖QT事件循环
QueueConnection 队列,次线程中执行,异步调用,槽函数所在对象得线程必须启用QT事件循环
BlockingQueuedConnection 阻塞联,同步调用, 槽函数在次线程中执行,用信号量实现阻塞,
槽函数所在对象得线程必须启用QT事件循环,此连接只能用于发
出信号得线程和槽函数执行线程不同得情况。
要么在发射信号得线程中执行
要么在接受者依附得线程中执行
线程安全