当我调用`QIODevice::readAll()` 时,QNetworkReply 会随机出现段错误,这通常与损坏的数据有关这是因为它还在营业吗?

问题描述

我很难追踪这个错误。 这是基本示例;它需要快速连接和许多同时下载。当它命中时,是相当随机的。

#ifndef DOWNLOAD_H
#define DOWNLOAD_H

#include <QThread>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QEventLoop>
#include <QFile>

class Download : public QThread
{
    Q_OBJECT
public:
    Download( const QString &path,QUrl url,QObject* parent = nullptr )
    : QThread(parent),f_Local(path),m_Url(url)
    {
        this->start();
    };

private:
    QFile f_Local;
    const QUrl m_Url;

    void run() override
    {
        qnetworkrequest request( m_Url );
        QNetworkAccessManager nam;
        QNetworkReply *reply = nam.get(request);
        {
            reply->setParent(&nam);
        }

        QEventLoop waitForDownload;
        connect( reply,&QNetworkReply::readyRead,[this,&reply](){
            if ( !f_Local.open(  qiodevice::writeonly | qiodevice::Append  ) ) {
                return;
            }
            f_Local.write( reply->readAll() );
            f_Local.close();
            qDebug()
            << f_Local.fileName()
            << Qt::endl
            << f_Local.size() << "/"
            << reply->header( qnetworkrequest::ContentLengthHeader ).toLongLong()
            << Qt::endl
            << m_Url.todisplayString()
            << Qt::endl;
        });
        connect( reply,&QNetworkReply::finished,&waitForDownload,&QEventLoop::quit );
        waitForDownload.exec();
    }
};

#endif // DOWNLOAD_H

This is a gdb trace 并且它表明当 QNetworkReply 尝试释放其缓存时发生了一些损坏

需要注意的重要一点是,我在 readAll()调用 readyRead() 而不是 finished(),这意味着它仍然能够将数据写入 QNetworkReply 对象.如果 readAll() 在写入缓冲区的同时清除缓冲区,这可能是一个问题吗?我是在 qiodevice / QNetworkReply 对此进行保护的假设下工作的。如果没有;有没有我可以调用的互斥锁来防止这种情况发生?

一个需要注意的重要事情是我的类是线程化的,我同时运行了近十几个线程,因此有十几个 QNetworkAccessManager 对象以及随后的 {{1} } 等

我原以为 QNetworkReply 可能在 Reply 准备完成之前已被删除,但阻止它仍然会给我带来错误

我的怀疑是正确的,还是有其他因素在起作用?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)