分享

QT多线程标准写法

 懒人海马 2023-08-04 发布于山东

foreach循环和范围for循环在这个特定的例子中的功能是相同的,都用于遍历threadPool列表中的线程对象,并调用quitwait方法,然后删除线程对象。

无论是使用foreach循环还是范围for循环,它们都可以正确地停止并等待每个线程的结束,并删除线程对象。因此,在这个例子中,两种循环的功能是相同的。

以下是两种循环的功能区别:

语法:foreach循环使用关键字foreach,而范围for循环使用冒号:

可迭代对象类型:foreach循环可以遍历任何可迭代对象(如容器、数组、字符串等),而范围for循环只能遍历具有迭代器的容器。

遍历方式:foreach循环通过值(拷贝)遍历容器中的元素,而范围for循环通过引用遍历容器中的元素。因此,在使用foreach循环时,对元素的修改不会影响容器中的元素,而在使用范围for循环时,对元素的修改会影响容器中的元素。

在这个特定的例子中,由于在循环内部删除了线程对象,所以两种循环的功能是相同的。但需要注意的是,删除了线程对象后,如果还需要继续使用threadPool列表,那么在删除线程对象之后,使用foreach循环可能会导致迭代错误,因为在循环内部删除了元素。在这种情况下,建议使用范围for循环,因为它通过引用遍历容器中的元素,不会受到删除操作的影响。

多线程标准写法:

QList<QThread*> threadPool;加入线程池只是为了

for (QThread *thread : threadPool) {

        thread->quit();

        thread->wait();

    }来触发 &QThread::finished信号。

#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QList>

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

public slots:
    void doWork()
    {
        qDebug() << "Worker thread:" << QThread::currentThreadId();
        // 执行工作任务
    }
};
QThread *workThread ;
Worker *worker ;
QList<QThread*> threadPool;
void createAndStartThread()
{
    // 创建工作线程
    workThread = new QThread();

    // 创建工作类实例
    worker = new Worker();

    // 将工作类移动到工作线程
    worker->moveToThread(workThread);

    // 连接工作线程的启动信号与工作类的槽函数
connect(workThread , &QThread::finished,worker, &QObject::deleteLater);
connect(worker, &QObject::destroyed, workThread , &QThread::deleteLater);
QObject::connect(workThread, &QThread::started, worker, &Worker::doWork);
QObject::connect( worker, &Worker::signal,this,SLOT(On()));
    // 启动工作线程
    workThread->start();

    // 添加到对象池中
    threadPool.append(workThread);
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    for (int i = 0; i < 5; i++) {
        createAndStartThread();
    }

    int result = a.exec();
    // 释放资源
    for (QThread *thread : threadPool) {
        thread->quit();
        thread->wait(); }
  return result;
}
多线程标准写法2:

#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QList>

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

public slots:
    void doWork()
    {
        qDebug() << "Worker thread:" << QThread::currentThreadId();
        // 执行工作任务
    }
};
QList<QThread*> threadPool;
void createAndStartThread()
{
    // 创建工作线程
    QThread *workThread = new QThread();

    // 创建工作类实例
    Worker *worker = new Worker();

    // 将工作类移动到工作线程
    worker->moveToThread(workThread);

    // 连接工作线程的启动信号与工作类的槽函数
    connect(workThread, &QThread::finished, worker, &QObject::deleteLater);
    connect(worker, &QObject::destroyed, workThread, &QThread::deleteLater);
    QObject::connect(workThread, &QThread::started, worker, &Worker::doWork);
    QObject::connect(worker, &Worker::signal, this, SLOT(On()));

    // 启动工作线程
    workThread->start();

    // 添加到对象池中
    threadPool.append(workThread);
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    for (int i = 0; i < 5; i++) {
        createAndStartThread();
    }

    // 等待应用程序退出
    int result = a.exec();

    // 释放资源
   for (QThread *thread : threadPool) {
        thread->quit();
        thread->wait();
    }
    return result;
}

循环创建实例化新的QThread对象的数量有限只有10个,只执行后1次循环,会不会导致内存泄漏的问题,为什么?

在只执行后1次循环的情况下,如果循环创建实例化新的QThread对象的数量有限只有10个,并且在每次实例化新对象之前不释放之前的对象,不会导致内存泄漏的问题。

由于只执行后1次循环,循环创建实例化新的QThread对象的数量有限只有10个,即只会创建10个对象。在这种情况下,即使不释放之前的对象,这10个对象仍然是有限的,不会无限制地占用内存。

当程序结束时,操作系统会自动释放程序所占用的内存,包括这10个QThread对象。因此,在只执行后1次循环的情况下,即使不释放之前的对象,也不会导致内存泄漏问题。

然而,如果在其他情况下,循环创建实例化新的QThread对象的数量超过10个,或者循环执行多次,那么不及时释放之前的对象就有可能导致内存泄漏问题。因此,为了确保代码的健壮性和可维护性,建议在每次实例化新对象之前都及时释放之前的对象。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多