1、线程启动
void start(Priority priority = InheritPriority)
调用后会执行run()函数,但在run()函数执行前会发射信号started(),操作系统将根据优先级参数调度线程。如果线程已经在运行,那么这个函数什么也不做。优先级参数的效果取决于操作系统的调度策略。特别是那些不支持线程优先级的系统优先级将会被忽略(例如在Linux中,更多细节请参考http://linux.die.net/man/2/sched_setscheduler)。
2、线程执行
int
进入事件循环并等待直到调用exit(),返回值是通过调用exit()来获得,如果调用成功则范围0。
virtual void
线程的起点,在调用start()之后,新创建的线程就会调用这个函数,默认实现调用exec(),大多数需要重新实现这个功能,便于管理自己的线程。该方法返回时,该线程的执行将结束。
3、线程退出
void quit()
告诉线程事件循环退出,返回0表示成功,相当于调用了QThread::exit(0)。
void exit(int returnCode = 0)
告诉线程事件循环退出。
调用这个函数后,线程离开事件循环后返回,QEventLoop::exec()返回returnCode,
按照惯例0表示成功,任何非0值表示失败。
void terminate()
终止线程,线程可能会立即被终止也可能不会,这取决于操作系统的调度策略,使用terminate()之后再使用QThread::wait()确保万无一失。
当线程被终止后,所有等待中的线程将会被唤醒。
警告:此功能比较危险,不鼓励使用。线程可以在代码执行的任何点被终止。线程可能在更新数据时被终止,从而没有机会来清理自己,解锁等等。。。总之,只有在绝对必要时使用此功能。
建议:一般情况下,都在run函数里面设置一个标识符,可以控制循环停止。然后才调用quit函数,退出线程。
4、线程等待
void msleep(unsigned long msecs)
强制当前线程睡眠msecs毫秒
void sleep(unsigned long secs)
强制当前线程睡眠secs秒
void usleep(unsigned long usecs)
强制当前线程睡眠usecs微秒
bool wait(unsigned long time = ULONG_MAX);
线程将会被阻塞,等待time毫秒。和sleep不同的是,如果线程退出,wait会返回。
5、线程状态
6、线程优先级
Constant | Value | Description |
QThread::IdlePriority | 0 | 没有其它线程运行时才调度. |
QThread::LowestPriority | 1 | 比LowPriority调度频率低. |
QThread::LowPriority | 2 | 比NormalPriority调度频率低. |
QThread::NormalPriority | 3 | 操作系统默认的默认优先级. |
QThread::HighPriority | 4 | 比NormalPriority调度频繁. |
QThread::HighestPriority | 5 | 比HighPriority调度频繁. |
QThread::TimeCriticalPriority | 6 | 尽可能频繁的调度. |
QThread::InheritPriority | 7 | 使用和创建线程同样的优先级. 这是默认值. |
在Qt之线程(QThread)一节中我介绍了QThread 的两种使用方法:
1、子类化 QThread(不使用事件循环)。
这是官方手册、例子以及相关书籍中都介绍的一种常用的方法。
a. 子类化 QThread
b. 重载 run 函数,run函数内有一个while或for的死循环(模拟耗时操作)
c. 设置一个标记为来控制死循环的退出。
2、子类化
a. 子类化
b.
c. 将该子类的对象moveToThread到新线程中
run 对于线程的作用相当于main函数对于应用程序。它是线程的入口,run的开始和结束意味着线程的开始和结束。
采用这两种做法,毫无疑问都会在次线程中运行(这里说的是,run中的逻辑以及子类化QObject后连接通过moveToThread然后连接到QThread的started()信号的槽函数,这个下面会详细讲解)。
那么,线程中的槽函数是怎么运行的呢?
说到信号与槽,大家应该再熟悉不过了,包括我,特别喜欢使用自定义信号与槽,感觉用起来特方便、特棒。。。
经常使用,你能否100%的使用正确?你了解它的高级用法吗?
1、你是否在多次connect,还发现不了为什么槽函数会执行那N多次。
2、你是否了解disconnect
3、你是否了解connect中的第五个参数
关于connect、disconnect信号、槽的使用可参考:Qt之信号与槽。既然谈到线程这里需要重点说下Qt::ConnectionType(信号与槽的传递方式)
Constant | Value | Description |
Qt::AutoConnection | 0 | 自动连接:(默认值)如果信号在接收者所依附的线程内发射,则等同于直接连接。如果发射信号的线程和接受者所依附的线程不同,则等同于队列连接。 |
Qt::DirectConnection | 1 | 直接连接:当信号发射时,槽函数将直接被调用。无论槽函数所属对象在哪个线程,槽函数都在发射信号的线程内执行。 |
Qt::QueuedConnection | 2 | 队列连接:当控制权回到接受者所依附线程的事件循环时,槽函数被调用。槽函数在接收者所依附线程执行。也就是说:这种方式既可以在线程内传递消息,也可以跨线程传递消息 |
Qt::BlockingQueuedConnection | 3 | 与Qt::QueuedConnection类似,但是会阻塞等到关联的slot都被执行。这里出现了阻塞这个词,说明它是专门用来多线程间传递消息的。 |
举例:
MyObject.h
MyObject.cpp
main.cpp
1、修改代码如下:
2、修改代码如下:
查看运行结果:
3、修改代码如下: