Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 已停止QRunnable原因主窗口不可关闭 平台:Qt4.8.2(使用MingWx64从源代码构建),Win7_Multithreading_Qt - Fatal编程技术网

Multithreading 已停止QRunnable原因主窗口不可关闭 平台:Qt4.8.2(使用MingWx64从源代码构建),Win7

Multithreading 已停止QRunnable原因主窗口不可关闭 平台:Qt4.8.2(使用MingWx64从源代码构建),Win7,multithreading,qt,Multithreading,Qt,我使用QRunnable将长时间运行的任务从主GUI线程中分离出来,有时我会遇到随机崩溃/奇怪的行为,没有可追踪的错误。请帮助提供关于调试内容/方式的建议。谢谢 Runner类:多继承,用于连接到主窗口的信号/插槽 class MyRunner : public QObject, public QRunnable { Q_OBJECT Q_SIGNALS: void feedbackLog(QString text); void finished(); public:

我使用QRunnable将长时间运行的任务从主GUI线程中分离出来,有时我会遇到随机崩溃/奇怪的行为,没有可追踪的错误。请帮助提供关于调试内容/方式的建议。谢谢

Runner类:多继承,用于连接到主窗口的信号/插槽

class MyRunner : public QObject, public  QRunnable
{
    Q_OBJECT
Q_SIGNALS:
    void feedbackLog(QString text);
    void finished();
public:
    explicit MyRunner(/* some args */) { /* some initialization */ }

    void run() {
        stopped_ = false;
        for (int run = 0; run < SOME_COUNT; run++) {

            Q_EMIT feedbackLog("Resetting everything ...");
            if (stopped_) return;

            /* start the daily interaction until the epidemic is over */
            do
            {
                if (stopped_) return;
                lengthySubTaskA();
                if (stopped_) return;
                lengthySubTaskB();
                if (stopped_) return;
                lengthySubTaskC();
            }
            while (conditionNotReached());
        } // end: for(run)
        stopped_ = true;
        Q_EMIT finished();
    }
    bool isStopped() { return stopped_; }
public Q_SLOTS:
    void stop() {
        Q_EMIT feedbackLog("Cancel ...");
        stopped_ = true;
    }
private:
    bool stopped_;
    /** other class members follow */
};
1) 如果在(a)处禁用自动删除,是否应添加语句(b)以防止泄漏?还是有更好的方法来处理泄漏

2) 有时,当Runnable任务完成时,我无法正常关闭应用程序(无论[x]按钮还是Alt-F4都不起作用),我必须从QtCreator中杀死应用程序(我正在调试,对吗?)。可能的原因是什么

[编辑]:3)对于不可关闭的主窗口,有时会在我取消MyRunner类处理的任务后发生,这是否可能是一个原因

[编辑]:我在(c)附近添加了qDebug()语句,发现如果[x]按钮没有响应,它会在(c)处停止并拒绝继续显示等待对话框


谢谢。

通过更改主窗口的“关闭策略”解决了此问题:删除“自动终止”并强制用户等待生成的线程。变量
runner\u
progress\u dialog\u
现在被本地化为函数
callMyRunnable()

为什么runner\u和progress\u dialog\u是类成员?您是否在其他地方访问它们?根据程序逻辑,它们应该是局部变量,因为每个callMyRunnable()都会有效地重置这些指针。如果您需要从其他任何地方访问它们,这可能是问题的根源,否则,我建议将它们设置为本地,以确保这些指针不会在运行程序的callMyRunnable()之外使用,我需要停止生成的线程,以防用户通过[x]按钮关闭主窗口,请检查我的关闭事件并查看语句(c)在我的岗位上。如果我只使用QThreadPool::waitForDone(),运行程序运行的任务可能需要数小时才能停止,这将冻结我的应用程序。对于progress\u dialog,我无法使用modal dialog,因为我希望用户在主窗口上与一些小部件交互。如果我将dialog.show()与局部变量一起使用,它会很快消失,用户没有机会取消任务。好的,但是如果您输入callMyRunnable()两次,第一个运行程序将不再可访问。如果您需要访问它-您需要一些指针容器来存储它们-比如std::vector,而不是MyRunner*。如果只有一个进度对话框/运行程序-在构造函数中创建它,在析构函数中删除它,只在callMyRunnable()中访问它们。如果您需要多个运行程序/对话框,则需要为它们提供一些容器。
void MainWindow::callMyRunnable() {
    runner_ = new MyRunner(/* args */); // runner_ is class member */
    runner_->setAutoDelete(true); // (a)
    progress_dialog_ = new QProgressDialog("Running", "Cancel", 0, 0, this);
    progress_dialog_->setAttribute(Qt::WA_DeleteOnClose);

    connect(runner_, SIGNAL(feedbackLog(QString)), SLOT(logMessage(QString)));
    connect(runner_, SIGNAL(finished()),           SLOT(endLengthyJob()));
    connect(runner_, SIGNAL(finished()), progress_dialog_, SLOT(close()));
    connect(progress_dialog_, SIGNAL(canceled()), runner_, SLOT(stop()));
    connect(progress_dialog_, SIGNAL(canceled()), SLOT(endLengthyJob()));

    QThreadPool::globalInstance()->start(runner_);
    progress_dialog_->show();
    /* flu_runner_->deleteLater(); */ // (b)
}

void MainWindow::closeEvent(QCloseEvent *e) {
     if (runner_ && !runner_->isStopped()) runner_->stop(); // (c)
     if (QThreadPool::globalInstance()->activeThreadCount())
     {
         /* display a dialog to notify user about shutdown */
         Dialog::WaitDialog dlg(5 * 1000);
         dlg.exec();
     }
     event->accept();
} // end_event(MainWindow::closeEvent)