回顾一下Qt的多线程技术以及实际开发常用场景

在 Qt 中,多线程编程是一项重要的技术,它允许程序同时执行多个任务,从而提高程序的性能和响应能力。下面将详细介绍 Qt 中的多线程编程,包括相关类、使用方法以及实际运用场景例子。

1. Qt 中多线程编程的相关类

QThread

QThread 是 Qt 中用于创建和管理线程的核心类。通过继承 QThread 并重写其 run() 方法,可以在新线程中执行自定义的任务。以下是一个简单的示例:

#include 
#include 

class MyThread : public QThread
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = nullptr) : QThread(parent) {}

protected:
    void run() override {
        for (int i = 0; i < 5; ++i) {
            qDebug() << "Thread ID:" << QThread::currentThreadId() << "Count:" << i;
            QThread::sleep(1);
        }
    }
};

在上述代码中,MyThread 类继承自 QThread,并重写了 run() 方法。在 run() 方法中,线程会每隔 1 秒输出一次当前线程的 ID 和计数。

QRunnable 和 QThreadPool

QRunnable 是一个抽象基类,用于表示可以在线程池中运行的任务。QThreadPool 是 Qt 提供的线程池类,它可以管理和复用线程,减少线程创建和销毁的开销。以下是一个使用 QRunnable 和 QThreadPool 的示例:

#include 
#include 
#include 

class MyRunnable : public QRunnable
{
public:
    void run() override {
        for (int i = 0; i < 3; ++i) {
            qDebug() << "Thread ID:" << QThread::currentThreadId() << "Count:" << i;
            QThread::sleep(1);
        }
    }
};

// 使用示例
void useThreadPool() {
    QThreadPool pool;
    MyRunnable *runnable = new MyRunnable();
    runnable->setAutoDelete(true); // 任务执行完后自动删除
    pool.start(runnable);
    pool.waitForDone(); // 等待所有任务完成
}

在上述代码中,MyRunnable 类继承自 QRunnable,并重写了 run() 方法。QThreadPool 会自动分配线程来执行 MyRunnable 任务。

2. 线程间通信

在多线程编程中,线程间通信是非常重要的。Qt 提供了信号和槽机制来实现线程间的安全通信。以下是一个示例:

#include 
#include 
#include 

// 工作线程类
class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr) : QObject(parent) {}

signals:
    void resultReady(const QString &result);

public slots:
    void doWork() {
        QString result = "Work done";
        emit resultReady(result);
    }
};

// 主线程类
class Controller : public QObject
{
    Q_OBJECT
public:
    explicit Controller(QObject *parent = nullptr) : QObject(parent) {
        worker = new Worker();
        thread = new QThread();
        worker->moveToThread(thread);

        connect(thread, &QThread::started, worker, &Worker::doWork);
        connect(worker, &Worker::resultReady, this, &Controller::handleResults);
        connect(worker, &Worker::resultReady, thread, &QThread::quit);
        connect(worker, &Worker::resultReady, worker, &Worker::deleteLater);
        connect(thread, &QThread::finished, thread, &QThread::deleteLater);

        thread->start();
    }

public slots:
    void handleResults(const QString &result) {
        qDebug() << "Received result:" << result;
    }

private:
    Worker *worker;
    QThread *thread;
};

在上述代码中,Worker 类在新线程中执行任务,并通过信号 resultReady 向主线程发送结果。Controller 类负责管理线程和接收结果。

3. 实际运用场景例子

网络请求

在开发网络应用程序时,网络请求可能会阻塞主线程,导致界面卡顿。使用多线程可以将网络请求放在新线程中执行,避免阻塞主线程。以下是一个简单的示例:

#include 
#include 
#include 
#include 
#include 

class NetworkWorker : public QObject
{
    Q_OBJECT
public:
    explicit NetworkWorker(QObject *parent = nullptr) : QObject(parent) {
        manager = new QNetworkAccessManager(this);
        connect(manager, &QNetworkAccessManager::finished, this, &NetworkWorker::handleNetworkReply);
    }

signals:
    void networkDataReceived(const QByteArray &data);

public slots:
    void performNetworkRequest(const QUrl &url) {
        QNetworkRequest request(url);
        manager->get(request);
    }

private slots:
    void handleNetworkReply(QNetworkReply *reply) {
        if (reply->error() == QNetworkReply::NoError) {
            QByteArray data = reply->readAll();
            emit networkDataReceived(data);
        } else {
            qDebug() << "Network error:" << reply->errorString();
        }
        reply->deleteLater();
    }

private:
    QNetworkAccessManager *manager;
};

// 使用示例
void performNetworkTask() {
    NetworkWorker *worker = new NetworkWorker();
    QThread *thread = new QThread();
    worker->moveToThread(thread);

    connect(thread, &QThread::started, [worker]() {
        worker->performNetworkRequest(QUrl("https://www.example.com"));
    });
    connect(worker, &NetworkWorker::networkDataReceived, [](const QByteArray &data) {
        qDebug() << "Received data:" << data;
    });
    connect(worker, &NetworkWorker::networkDataReceived, thread, &QThread::quit);
    connect(worker, &NetworkWorker::networkDataReceived, worker, &NetworkWorker::deleteLater);
    connect(thread, &QThread::finished, thread, &QThread::deleteLater);

    thread->start();
}

在上述代码中,NetworkWorker 类在新线程中执行网络请求,并通过信号 networkDataReceived 将请求结果发送给主线程。

大数据处理

在处理大量数据时,如文件读写、图像处理等,可能会消耗大量的时间。使用多线程可以将数据处理任务分配到多个线程中并行执行,提高处理效率。以下是一个简单的文件读取示例:

#include 
#include 
#include 
#include 

class FileReader : public QObject
{
    Q_OBJECT
public:
    explicit FileReader(QObject *parent = nullptr) : QObject(parent) {}

signals:
    void fileReadFinished(const QString &content);

public slots:
    void readFile(const QString &fileName) {
        QFile file(fileName);
        if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QTextStream in(&file);
            QString content = in.readAll();
            file.close();
            emit fileReadFinished(content);
        } else {
            qDebug() << "Failed to open file:" << fileName;
        }
    }
};

// 使用示例
void performFileReadTask() {
    FileReader *reader = new FileReader();
    QThread *thread = new QThread();
    reader->moveToThread(thread);

    connect(thread, &QThread::started, [reader]() {
        reader->readFile("test.txt");
    });
    connect(reader, &FileReader::fileReadFinished, [](const QString &content) {
        qDebug() << "File content:" << content;
    });
    connect(reader, &FileReader::fileReadFinished, thread, &QThread::quit);
    connect(reader, &FileReader::fileReadFinished, reader, &FileReader::deleteLater);
    connect(thread, &QThread::finished, thread, &QThread::deleteLater);

    thread->start();
}

在上述代码中,FileReader 类在新线程中读取文件内容,并通过信号 fileReadFinished 将文件内容发送给主线程。

你可能感兴趣的:(qt,lucene,数据库)