Qt,QMutex:销毁锁定的互斥然后应用程序崩溃
我使用QNetworkAccessManager进行http操作(get、post等)。我并行运行了一些“get”操作。为此,我使用QtConcurrent::run(this,&RestWebservice::GetHTTPData)进行多HTTP操作。 我的问题是,当我在HTTP操作未完成之前关闭应用程序时,应用程序崩溃。应用程序输出写入此行QMutex:销毁锁定的互斥锁,然后写入程序意外完成。 我认为这一行出现了客户问题Qt,QMutex:销毁锁定的互斥然后应用程序崩溃,qt,qtconcurrent,Qt,Qtconcurrent,我使用QNetworkAccessManager进行http操作(get、post等)。我并行运行了一些“get”操作。为此,我使用QtConcurrent::run(this,&RestWebservice::GetHTTPData)进行多HTTP操作。 我的问题是,当我在HTTP操作未完成之前关闭应用程序时,应用程序崩溃。应用程序输出写入此行QMutex:销毁锁定的互斥锁,然后写入程序意外完成。 我认为这一行出现了客户问题 void RestWebservice::get() { //
void RestWebservice::get()
{
// mutex.lock();
m_networkManager.get(m_networkrequest);
// mutex.unlock();
}
但我不确定,因为QtCreater调试器不像VS那么好。顺便说一句,GetHTTPData在不同的类中
启动网络操作的代码:(MobileOperation.cpp)。例如,getUserAccount我启动http操作
void MobileOperations::getWorkOrderListT(int ekipId) {
MyGlobal::Metods metod=MyGlobal::EkipIsEmriListesi;
QString parameters="{EkipId}";
QMap<QString,QVariant> paramlist;
paramlist["EkipId"]=ekipId;
GetHTTPData(metod,parameters,paramlist);
if(m_workorder.IsSuccess==true)
{
// emit successupdatewo();
if(m_workorder.workorders.count()>0)
{
InsertWo(json.workorder->workorders);
emit processstop("İş Emri Listesi Güncellendi");
// QThread::sleep(2);
}
else
{
emit processstop(json.workorder->ReturnMessage);
}
emit successworkstart();
}
else
{
emit processstop("Bağlantı Başarısız Oldu");
}
}
void MobileOperations::getUserAccount(QString kullaniciAdi, QString sifre,bool isremember)
{
json.user=m_user;
QtConcurrent::run(this,&MobileOperations::getUserAccountT,kullaniciAdi,sifre,isremember);
// getUserAccountT(kullaniciAdi,sifre,isremember);
processstart("Baglaniyor");
}
void MobileOperations::GetHTTPData(MyGlobal::Metods MetodName, QString Parameters, QMap<QString, QVariant> paramlist)
{
try
{
parameter=new HttpRequest();
parameter->url=m_url;
parameter->metodname=MetodName;
parameter->resource=m_path;
parameter->appid=m_appid;
parameter->apppass=m_apppass;
parameter->parametersname=Parameters;
parameter->params=paramlist;
rest= new RestWebservice(parameter->GenerateHTTPQuery(),MetodName);
// json=new JSonParser();
// loop=new QEventLoop();
loop=new QEventLoop();
QObject::connect(rest,SIGNAL(sendhttpdata(QByteArray,MyGlobal::Metods)),&json,SLOT(onGetData(QByteArray,MyGlobal::Metods)));
QObject::connect(&json,SIGNAL(serilazitionCompleted()),loop,SLOT(quit()));
rest->get();
loop->exec();
}
catch(std::string &exp)
{
qDebug()<<"Sonlandırıldı";
}
}
void MobileOperations::GetWorkOrderList(int ekipId){
MyGlobal::Metods metod=MyGlobal::ekipisemirlistesi;
QString参数=“{EkipId}”;
QMap参数列表;
paramlist[“EkipId”]=EkipId;
GetHTTPData(metod、参数、参数列表);
if(m_workorder.issucess==true)
{
//emit successupdatewo();
如果(m_workorder.workorders.count()>0)
{
InsertWo(json.workorder->workorder);
发射进程停止(“Emri Listesi Güncellendi”);
//QThread::sleep(2);
}
其他的
{
发出processstop(json.workorder->ReturnMessage);
}
emit successworkstart();
}
其他的
{
排放过程停止(“BağlantıBaşarısız Oldu”);
}
}
void MobileOperations::getUserAccount(QString kullaniciAdi、QString sifre、bool isremember)
{
json.user=m_user;
QtConcurrent::run(this,&MobileOperations::getuseraccount、kullaniciAdi、sifre、isremember);
//GetUserAccount(kullaniciAdi、sifre、isremember);
processstart(“Baglaniyor”);
}
void MobileOperations::GetHTTPData(MyGlobal::Metods MetodName、QString参数、QMap参数列表)
{
尝试
{
参数=新的HttpRequest();
参数->url=m_url;
参数->metodname=metodname;
参数->资源=m_路径;
参数->appid=m_appid;
参数->apppass=m_apppass;
参数->参数名称=参数;
参数->参数=参数列表;
rest=新的RestWebservice(参数->GenerateHTTPQuery(),MetodName);
//json=新的JSonParser();
//loop=新的QEventLoop();
loop=新的QEventLoop();
QObject::connect(rest,信号(sendhttpdata(QByteArray,MyGlobal::Metods)),&json,插槽(onGetData(QByteArray,MyGlobal::Metods));
QObject::connect(&json,信号(serializationCompleted()),循环,插槽(quit());
rest->get();
循环->执行();
}
catch(std::string和exp)
{
qDebug()是否将互斥锁作为类的成员。在这种情况下,互斥锁在解锁之前被销毁(我假设包含的类超出范围),这会导致出现您看到的消息。当类被销毁时,会调用互斥锁的析构函数,而锁被持有。这是一个问题。通常,您必须找到一种方法,在网络请求期间不无限期地阻塞。您不需要使用QtConcurrent::run()
要并行运行多个get操作,QNetworkAccessManager
是异步的,因此您可以在同一线程中启动多个请求并连接它们的readyRead()
向处理它们的插槽发送信号。请告诉我们线程的具体工作方式,因为我认为您必须更改设计…@Mike,如果我不使用QtConcurrent::run,应用程序窗口将冻结。我不使用互斥。这不起作用。我只进行了尝试,然后是包含互斥的commet行。当您使用互斥时,问题就出现了与互斥体相关。
#include "restwebservice.h"
#include <QJsonDocument>
#include<QJsonArray>
#include <QJsonObject>
#include<QJsonValue>
#include<QList>
#include <QThread>
RestWebservice::RestWebservice(QNetworkRequest request,
MyGlobal::Metods metod,
QObject* parent):QObject(parent),m_networkrequest(request),m_metodname(metod)
{
connect(&m_networkManager, SIGNAL(finished(QNetworkReply*)),this, SLOT(onResult(QNetworkReply*)));
// connect(&m_networkManager,SIGNAL())
}
void RestWebservice::get()
{
// mutex.lock();
m_networkManager.get(m_networkrequest);
// mutex.unlock();
}
void RestWebservice::post(QString request)
{
QByteArray requestA= request.toUtf8();
m_networkManager.post(m_networkrequest,requestA);
}
void RestWebservice::onResult(QNetworkReply* reply)
{
try
{
if (reply->error() != QNetworkReply::NoError)
{
qDebug()<<reply->error()<<":"<<reply->errorString();
MyGlobal::NetworkStatus=reply->errorString();
emit sendhttpdata(m_data,m_metodname);
return;
// throw(reply->errorString().toStdString());
}
QByteArray data = reply->readAll();
reply->deleteLater();
m_data=data;
MyGlobal::NetworkStatus="Tablolar Yüklendi";
emit sendhttpdata(m_data,m_metodname);
}
catch(std::string exp)
{
qDebug()<<"Exception:"<<QString::fromStdString(exp);
}
catch(std::exception &exp)
{
qDebug()<<"Exception:"<<QString::fromStdString(exp.what());
}
}
void RestWebservice::onError()
{
qDebug()<<"Hata VAR";
}
HttpRequest::HttpRequest(QObject *parent) :
QObject(parent)
{
}
QNetworkRequest HttpRequest::GenerateHTTPQuery()
{
// QString path="";
QString path=QString("/%1/%2/%3/%4/%5").arg(resource).arg(MyGlobal::getMetodName(metodname)).arg(appid).arg(apppass).arg(parametersname);
foreach (QString param, params.keys()) {
path.replace("{"+param+"}",params[param].toString());
}
QUrl m_url(url);
m_url.setPath(path);
m_request.setUrl(m_url);
m_request.setRawHeader("Content-Type","application/json;charset=utf-8");
// m_request.setRawHeader("SOAPAction","http://tempuri.org/IMobileClient/UserAuth");
qDebug()<<m_url.url();
return m_request;
}
QNetworkRequest HttpRequest::GenerateHTTPQueryPost()
{
// QString path="";
QString path=QString("/%1/%2").arg(resource).arg(MyGlobal::getMetodName(metodname));
QUrl m_url(url);
m_url.setPath(path);
m_request.setUrl(m_url);
m_request.setRawHeader("Content-Type","application/json;charset=utf-8");
// m_request.setRawHeader("SOAPAction","http://tempuri.org/IMobileClient/UserAuth");
qDebug()<<m_url.url();
return m_request;
}