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事件循环,此连接只能用于发

 出信号得线程和槽函数执行线程不同得情况。

要么在发射信号得线程中执行

要么在接受者依附得线程中执行

线程安全