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 事件循环, 此连接只能用于发
出信号得线程和槽函数执行线程不同得情况.
要么在发射信号得线程中执行
要么在接受者依附得线程中执行
线程安全
来源: http://www.bubuko.com/infodetail-3025985.html