0
点赞
收藏
分享

微信扫一扫

shell的一些练习。

大雁f 2023-05-31 阅读 120

方法一:从QThread类派生

这种方法涉及到创建一个从QThread类派生的子类,并在该子类中重写run()函数。处理操作将在这个函数中进行。然后在主线程中创建子线程对象,并通过调用start()函数启动子线程。

class WorkerThread : public QThread
{
    Q_OBJECT
    void run() override {
        /* ... here is the expensive or blocking operation ... */
    }
};

void MyObject::startWorkInAThread()
{
    WorkerThread *workerThread = new WorkerThread(this);
    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    workerThread->start();
}

方法二:使用业务处理类

这种方法涉及到将业务处理抽象成一个业务类,并在该类中创建一个业务处理函数。然后在主线程中创建一个QThread类对象和一个业务类对象。通过QObject::moveToThread()将业务类对象移动到子线程中,然后在主线程中启动子线程。通过信号槽的方式,执行业务类中的业务处理函数。

class Worker : public QObject
{
    Q_OBJECT
public slots:
    void doWork(const QString &parameter) {
        /* ... here is the expensive or blocking operation ... */
        emit resultReady(result);
    }
signals:
    void resultReady(const QString &result);
};

class Controller : public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    Controller() {
        Worker *worker = new Worker;
        worker->moveToThread(&workerThread);
        connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
        connect(this, &Controller::operate, worker, &Worker::doWork);
        connect(worker, &Worker::resultReady, this, &Controller::handleResults);
        workerThread.start();
    }
    ~Controller() {
        workerThread.quit();
        workerThread.wait();
    }
public slots:
    void handleResults(const QString &);
signals:
    void operate(const QString &);
};

方法三:使用QThreadPool和QRunnable

QThreadPool管理一组线程。你可以使用QThreadPool类来复用已经创建的线程,这可以避免线程创建和销毁的开销。QRunnable是一个可以在QThreadPool中运行的任务。

class Worker : public QRunnable
{
    void run() override
    {
        // Your code here
    }
};

QThreadPool *pool = QThreadPool::globalInstance();
Worker *worker = new Worker();
pool->start(worker);

方法四:使用QtConcurrent

QtConcurrent模块提供了一些高级函数,可以将函数调用或计算分发到多个线程中。这些函数返回一个QFuture对象,你可以使用这个对象来查询计算的状态和结果。

QFuture<int> future = QtConcurrent::run([]() -> int {
    // Your code here
    return result;
});

这些方法都是Qt中常见的线程处理方式,选择哪种方式取决于你的具体需求和编程风格。

多线程使用注意事项

  1. 业务对象,构造的时候不能指定父对象

  2. 子线程中不能处理ui窗口(ui相关的类)

  3. 子线程中只能处理一些数据相关的操作, 不能涉及窗口 除了这三条继续介绍用简短精炼的话

  4. 线程安全:在多线程环境中,需要确保数据的线程安全。如果多个线程访问和修改同一份数据,需要使用锁(如QMutex)或其他同步机制来防止数据竞争。

  5. 资源管理:线程的创建和销毁需要消耗资源,因此需要谨慎管理线程的生命周期。对于一些短期的任务,可以考虑使用线程池来复用线程。

  6. 错误处理:线程中的错误处理是一个复杂的问题。需要确保线程中的错误能够被正确捕获和处理,而不是导致整个程序崩溃。

  7. 通信:线程之间的通信通常通过信号和槽进行。需要注意的是,Qt的信号和槽机制在多线程环境中是线程安全的。

  8. 阻塞操作:在子线程中进行阻塞操作时,需要确保这不会影响到主线程的响应性。如果一个操作可能会花费很长时间,应该在一个单独的线程中进行。

  9. 优先级:可以通过设置线程的优先级来控制线程的执行顺序。但是需要注意的是,线程优先级的设置可能会受到操作系统的影响和限制。

举报

相关推荐

0 条评论