Qt5主线程发射信号阻塞,子线程执行速度慢。请教大神如何解决?

fightinghui1121 2018-05-03 03:24:46
背景:界面按下开始按钮进入Qt5主线程run()函数,发送协议帧,另一上位机收到发送帧后返回响应帧。在接收到响应帧后解析并将有效数据位存入队列。主线程提取队列数据存入缓存vector,然后发射信号,槽函数根据点坐标做数据处理,并实时绘制点。
问题:发射信号阻塞,子线程执行速度慢。导致按下停止按钮后槽函数仍运行一段时间才停止,并且重复开始按钮和停止按钮三次左右点击停止按钮不响应了或出现了延迟,仍然在绘图。。请教各路大神有什么好的意见和建议。期待大神回复。谢谢!
开始按钮:
void delay_scan::on_pushButton_delay_scan_start_clicked()
{
if(DelayScanThreadP->isRunning()==true)
{
qDebug("线程还在运行!\r\n");
DelayScanThreadP->quit();
DelayScanThreadP->msleep(100);
}
DelayScanThreadP->start();
qDebug("ready for goto thread!!!");
DelayScanData.GetDelayScanThreadCtl(&DelayScanThreadCtl);
DelayScanThreadCtl.DelayScanScanFlag=true;
DelayScanData.SetDelayScanThreadCtl(&DelayScanThreadCtl);
ui->pushButton_delay_scan_start->setEnabled(false);
ui->pushButton_delay_scan_stop->setEnabled(true);
}
停止按钮
void delay_scan::on_pushButton_delay_scan_stop_clicked()
{
qDebug("zh_func = %s, line=%d\r\n",__FUNCTION__,__LINE__);
if(DelayScanThreadP->isRunning() == false)
{
qDebug("线程停止!\r\n");
}
DelayScanThreadP->quit();
DelayScanThreadP->msleep(100);
DelayScanThreadCtlT DelayScanThreadCtl;
DelayScanData.GetDelayScanThreadCtl(&DelayScanThreadCtl);
DelayScanThreadCtl.DelayScanScanFlag=false;
DelayScanThreadCtl.stop_thread_flag=true;
DelayScanThreadCtl.thread_run_state=true;
DelayScanData.SetDelayScanThreadCtl(&DelayScanThreadCtl);
ui->pushButton_delay_scan_start->setEnabled(true);
ui->pushButton_delay_scan_stop->setEnabled(false);
}
connect(DelayScanThreadP, SIGNAL(scanned_signal()), this, SLOT(scanned_slot()));
子线程程主要代码:
void delay_scan_thread::run()
{
while(1)
{
DelayScanData.GetDelayScanThreadCtl(&DelayScanThreadCtl);
if(DelayScanThreadCtl.stop_thread_flag==true)
{
break;
}
if(DelayScanThreadCtl.DelayScanScanFlag==true)
{
DelayScanData.GetDelayScanThreadCtl(&DelayScanThreadCtl);
qDebug(" DelayScanThreadCtl.DelayScanScanFlag=%d", DelayScanThreadCtl.DelayScanScanFlag);

int ret;
for(uint16_t channel_count=0;channel_count<CHANNEL;channel_count++)
{
DelayScanData.GetDelayScanGlobalData(&DelayScanGlobalData);
if(DelayScanGlobalData.enable[channel_count]==false)
{
ChannelDataT[channel_count].EndSan=true;
ChannelDataT[channel_count].DelayScanScanState=false;
DelayScanData.GetDelayScanGlobalData(&DelayScanGlobalData);
DelayScanGlobalData.EndSan[channel_count]=true;
DelayScanGlobalData.DelayScanState[channel_count]=false;
DelayScanData.SetDelayScanGlobalData(&DelayScanGlobalData);
}
}
DelayScanData.GetDelayScanGlobalData(&DelayScanGlobalData);
if(DelayScanGlobalData.enable[0]==true||DelayScanGlobalData.enable[1]==true||DelayScanGlobalData.enable[2]==true||DelayScanGlobalData.enable[3]==true)
{
ret=DelayScanSendGateDelayPack(ChannelDataT);
ret=DelayScanSendProbeCountPack(ChannelDataT);//发送报文
}
else
{
break;
}
if(ret < 0)
{
break;
}
for(int channel_count = 0; channel_count < CHANNEL; channel_count++)
{
if(ChannelDataT[channel_count].EndSan == true) {
continue;
}
if(ChannelDataT[channel_count].Delay>DelayScanGlobalData.DelayEnd[channel_count])
{
ChannelDataT[channel_count].EndSan = true;
ChannelDataT[channel_count].DelayScanScanState = true;
DelayScanData.GetDelayScanGlobalData(&DelayScanGlobalData);
DelayScanGlobalData.EndSan[channel_count] = true;
DelayScanGlobalData.DelayScanState[channel_count] = true;
DelayScanData.SetDelayScanGlobalData(&DelayScanGlobalData);
}
else
{
QPointF point;
point.rx()=ChannelDataT[channel_count].Delay;
point.ry()=ChannelDataT[channel_count].CurCountValue;
point.ry()=point.rx();
DataVector[channel_count]<<point; //添加点到队列
emit scanned_signal();
DelayScanData.GetDelayScanGlobalData(&DelayScanGlobalData);
ChannelDataT[channel_count].Delay+=DelayScanGlobalData.step;
}
}
if(ChannelDataT[0].EndSan&&ChannelDataT[1].EndSan&&ChannelDataT[2].EndSan&&ChannelDataT[3].EndSan)
{
DelayScanThreadCtl.DelayScanScanFlag=false;
DelayScanData.SetDelayScanThreadCtl(&DelayScanThreadCtl);
break;
}
}
}
}
槽函数部分代码:
void delay_scan::scanned_slot()
{
if(DelayScanThreadCtl.stop_thread_flag==true)
{
return;
}
DelayScanQMutex.lock();
for(int i=0;i<CHANNEL;i++)
{
DataVector_temp[i]=DataVector[i];
}
DelayScanQMutex.unlock();
static int size_temp[4]={0};
if((DataVector_temp[0].size()-size_temp[0]==0)&&(DataVector_temp[1].size()-size_temp[1]==0)&&\
(DataVector_temp[2].size()-size_temp[2]==0)&&(DataVector_temp[3].size()-size_temp[3]==0))
{
return;
}
for(int i=0;i<CHANNEL;i++)
{
size_temp[i]=DataVector_temp[i].size();
}
double x_max_value[4] = {0.0,0.0,0.0,0.0};
double x_min_value[4] = {0.0,0.0,0.0,0.0};
double y_max_value[4] = {0.0,0.0,0.0,0.0};
double y_min_value[4] = {0.0,0.0,0.0,0.0};
for(int i = 0; i < CHANNEL; i++)
{
DelayScanData.GetDelayScanGlobalData(&DelayScanGlobalData);
if(DelayScanGlobalData.enable[i])
{
if(DelayScancustomPlotx[i].size() > 0)
{
DelayScancustomPlotx[i].clear();
}
if(DelayScancustomPloty[i].size() > 0)
{
DelayScancustomPloty[i].clear();
}
int size = DataVector_temp[i].size();
float x_axis = 0.0;
float temp;
float y_axis = 0.0;
if(size > 0)
{
y_axis = DataVector_temp[i].at(0).y();//i=CHANNEL,at()=数组大小
x_axis = DataVector_temp[i].at(0).x();
for (int j = 0; j < size; j++)
{
temp = DataVector_temp[i].at(j).y();
if(j == 0)
{
x_max_value[i] = DataVector_temp[i].at(j).x();

x_min_value[i] = DataVector_temp[i].at(j).x();

y_max_value[i] = DataVector_temp[i].at(j).y();

y_min_value[i] = DataVector_temp[i].at(j).y();
}
if(x_max_value[i] < DataVector_temp[i].at(j).x())
{
x_max_value[i] = DataVector_temp[i].at(j).x();
}
if(x_min_value[i] > DataVector_temp[i].at(j).x())
{
x_min_value[i] = DataVector_temp[i].at(j).x();
}
if(y_max_value[i] < DataVector_temp[i].at(j).y())
{
y_max_value[i] = DataVector_temp[i].at(j).y();
}
if(y_min_value[i] > DataVector_temp[i].at(j).y())
{
y_min_value[i] = DataVector_temp[i].at(j).y();
}
/* 填充cutomplot start*/
DelayScancustomPlotx[i].append(DataVector_temp[i].at(j).x());
DelayScancustomPloty[i].append(DataVector_temp[i].at(j).y());
/* 填充clutomplot end*/
if(y_axis < temp)
{
y_axis = temp;
x_axis = DataVector_temp[i].at(j).x();
}
}
DelayScanData.GetDelayScanGlobalData(&DelayScanGlobalData);
DelayScanGlobalData.MaxPeak[i] = y_axis;
DelayScanData.SetDelayScanGlobalData(&DelayScanGlobalData);
char buf[30];
switch(i)
{
case 0:
sprintf(buf, "%d ", (uint16_t)y_axis);

ui->label_max_peak_ch1->setText(QString(buf));
break;
case 1:
sprintf(buf, "%d ", (uint16_t)y_axis);
ui->label_max_peak_ch2->setText(QString(buf));
break;
case 2:
sprintf(buf, "%d ", (uint16_t)y_axis);
ui->label_max_peak_ch3->setText(QString(buf));
break;
case 3:
sprintf(buf, "%d ", (uint16_t)y_axis);
ui->label_max_peak_ch4->setText(QString(buf));
break;
}
}
}
}
DelayScanData.GetDelayScanGlobalData(&DelayScanGlobalData);
for(int i=0;i<CHANNEL;i++)
{
if(DelayScanGlobalData.enable[i])
{
SetupCurve(DelayScancustomPlot[i],DelayScancustomPlotx[i],DelayScancustomPloty[i],DelayScanGlobalData.DelayEnd[i],DelayScanGlobalData.DelayStart[i],y_max_value[i],y_min_value[i]);//绘图
}
}
}
...全文
2229 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
Marcelxx 2018-05-04
  • 打赏
  • 举报
回复
connect的时候已队列的方式连接,这样子线程和主线程各自执行各的,主线程就不会阻塞了。 如果一定要让主线程等待子线程执行完,可以在主线程中加QEventLoop事件循环等待子线程执行完再推出事件循环。

16,216

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧