一、Qt 中的多线程编程
Qt 中通过 QThread 直接支持多线程 — QThread 是一个跨平台的多线程解决方案 — QThread 以简洁易用的方式实现多线程编程 QThread 中的关键成员函数 — void run() : 线程体函数,用于定义线程功能(执行流)(相当于主线程的入口函数main()) — void start() : 启动函数,将线程入口地址设置为run函数 — void terminate() : 强制结束线程(不推荐) QThread 编程实例main.cpp
#include <QCoreApplication> # include <QThread> #include <QDebug> class MyThread : public QThread { protected: void run() //线程的入口地址 { qDebug() << objectName() << ":" << "run() begin"; for(int i = 0; i < 5; i++) { qDebug() << objectName() << ":" << i; sleep(1); } qDebug() << objectName() << ":" << "run() end"; } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "Main Begin"; MyThread t; t.setObjectName("t"); t.start(); //创建一个线程,执行这个线程 MyThread tt; tt.setObjectName("tt"); tt.start(); for(int i = 0; i < 1000000; i++) //延迟操作 { for(int j = 0; j < 10000; j++) { } } qDebug() << "Main End"; return a.exec(); }线程的生命周期 重点注意:在工程开发中 terminate() 是禁止使用的,terminate()会使得操作系统暴力终止线程,而不会考虑数据完整性,资源释放等问题
线程终止的解决思路 1、 run() 函数执行结束是优雅终止线程的唯一方式 2、在线程类中增加标志变量 m_toStop(volatile bool)类型,一定注意不要让编译器优化 3、通过 m_toStop 的值判断是否需要从 run 函数中返回
暴力结束线程(可能 new 出来的没 delete,导致内存泄露)与优雅结束线程:
main.cpp
#include <QCoreApplication> #include <QThread> #include <QDebug> class Sample : public QThread { protected: volatile bool m_toStop; void run() { qDebug() << objectName() << ": begin"; for(int i = 0; !m_toStop && i < 10; i++) { qDebug() << objectName() << ": " << i; msleep(500); } qDebug() << objectName() << ": end"; } public: Sample() { m_toStop = false; } void stop() { m_toStop = true; } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "main begin"; Sample t; t.setObjectName("t"); t.start(); for(int i=0; i<100000; i++) { for(int j=0; j<50000; j++) { } } t.stop(); //t.terminate(); qDebug() << "main end"; return a.exec(); }如果用t.terminate();进行线程结束,结果会是这样: 这条语句没有输出,如果这里涉及到内存释放,那么内存就无法释放。所以,在工程开发中 terminate() 是禁止使用的
小结 1、 QThread 是一个跨平台的多线程解决方案 2、 QThread 以简洁易用的方式实现多线程编程 3、 void run() 函数用于实现线程执行体 4、 void strat() 启动线程并执行 run() 函数 5、 工程中禁用 void terminate() 函数结束线程