无论是使用foreach循环还是范围for循环,它们都可以正确地停止并等待每个线程的结束,并删除线程对象。因此,在这个例子中,两种循环的功能是相同的。 以下是两种循环的功能区别: 语法: 可迭代对象类型:foreach循环可以遍历任何可迭代对象(如容器、数组、字符串等),而范围 遍历方式: 在这个特定的例子中,由于在循环内部删除了线程对象,所以两种循环的功能是相同的。但需要注意的是,删除了线程对象后,如果还需要继续使用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个,或者循环执行多次,那么不及时释放之前的对象就有可能导致内存泄漏问题。因此,为了确保代码的健壮性和可维护性,建议在每次实例化新对象之前都及时释放之前的对象。 |
|