qt中的多线程
阅读数:104 评论数:0
跳转到新版页面分类
C/C++
正文
一、基本概念
在 Qt 中,QThread
类用于表示一个线程。你可以通过继承 QThread
或者将对象移动到线程来实现多线程编程。推荐的方法是将对象移动到线程,因为它更符合 Qt 的信号槽机制。
二、创建和启动线程
1、继承QThread
这种方法通过继承 QThread
并重写 run
方法来实现线程任务。
#include <QThread>
#include <QDebug>
class MyThread : public QThread {
Q_OBJECT
protected:
void run() override {
for (int i = 0; i < 5; ++i) {
qDebug() << "Thread running" << i;
QThread::sleep(1);
}
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MyThread thread;
thread.start();
thread.wait(); // 等待线程结束
return app.exec();
}
2、将对象移动到线程
这种方法更推荐,因为它更符合 Qt 的信号槽机制,并且更容易管理对象的生命周期。
#include <QThread>
#include <QObject>
#include <QDebug>
class Worker : public QObject {
Q_OBJECT
public slots:
void doWork() {
for (int i = 0; i < 5; ++i) {
qDebug() << "Worker running" << i;
QThread::sleep(1);
}
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QThread workerThread;
Worker worker;
worker.moveToThread(&workerThread);
QObject::connect(&workerThread, &QThread::started, &worker, &Worker::doWork);
QObject::connect(&workerThread, &QThread::finished, &worker, &QObject::deleteLater);
workerThread.start();
workerThread.wait(); // 等待线程结束
return app.exec();
}
三、线程间通信
Qt 的信号槽机制可以跨线程工作。你可以使用信号槽在线程之间传递数据。
#include <QThread>
#include <QObject>
#include <QDebug>
class Worker : public QObject {
Q_OBJECT
public slots:
void doWork() {
for (int i = 0; i < 5; ++i) {
qDebug() << "Worker running" << i;
emit progress(i);
QThread::sleep(1);
}
emit finished();
}
signals:
void progress(int value);
void finished();
};
class Controller : public QObject {
Q_OBJECT
public slots:
void onProgress(int value) {
qDebug() << "Progress:" << value;
}
void onFinished() {
qDebug() << "Task finished!";
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QThread workerThread;
Worker worker;
Controller controller;
worker.moveToThread(&workerThread);
QObject::connect(&workerThread, &QThread::started, &worker, &Worker::doWork);
QObject::connect(&worker, &Worker::progress, &controller, &Controller::onProgress);
QObject::connect(&worker, &Worker::finished, &controller, &Controller::onFinished);
QObject::connect(&worker, &Worker::finished, &workerThread, &QThread::quit);
QObject::connect(&workerThread, &QThread::finished, &worker, &QObject::deleteLater);
workerThread.start();
return app.exec();
}
四、线程安全
在多线程编程中,确保线程安全非常重要。Qt 提供了 QMutex
、QReadWriteLock
、QSemaphore
等类来实现线程同步。
1、使用QMutex保护共享数据
#include <QThread>
#include <QMutex>
#include <QDebug>
class Counter {
public:
void increment() {
QMutexLocker locker(&mutex);
++value;
qDebug() << "Counter value:" << value;
}
private:
int value = 0;
QMutex mutex;
};
class Worker : public QThread {
Q_OBJECT
public:
Worker(Counter *counter) : counter(counter) {}
protected:
void run() override {
for (int i = 0; i < 5; ++i) {
counter->increment();
QThread::sleep(1);
}
}
private:
Counter *counter;
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
Counter counter;
Worker worker1(&counter);
Worker worker2(&counter);
worker1.start();
worker2.start();
worker1.wait();
worker2.wait();
return app.exec();
}
五、线程池
Qt 提供了 QThreadPool
和 QRunnable
来管理和执行多个线程任务。线程池可以重复使用线程,从而减少线程创建和销毁的开销。
#include <QThreadPool>
#include <QRunnable>
#include <QDebug>
class Task : public QRunnable {
public:
void run() override {
for (int i = 0; i < 5; ++i) {
qDebug() << "Task running" << i;
QThread::sleep(1);
}
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QThreadPool pool;
Task *task1 = new Task();
Task *task2 = new Task();
pool.start(task1);
pool.start(task2);
pool.waitForDone();
return app.exec();
}
六、QThread::sleep
QThread::sleep()
是一个静态方法,用于让当前线程暂停执行一段时间。它有几个不同的版本,分别用于秒、毫秒和微秒级别的暂停。
1、秒级暂停
QThread::sleep(2); // 暂停当前线程2秒
2、毫秒级暂停
QThread::msleep(500); // 暂停当前线程500毫秒
3、微秒级暂停
QThread::usleep(1000); // 暂停当前线程1000微秒(1毫秒)
相关推荐
一、基本使用
1、从Qt官方网站下载并安装Qt installer Framework
2、构建你的应用程序
qmake
make
3、创建安装项目结构
installer/
├── config/