我用Qt编写了一个数据采集程序。我使用QSemphore
编写的双缓存区域的子线程收集数据。
void QThreadShow::run() {
m_stop=false; // when start thread,m_stop=false
int n=fullBufs.available();
if (n>0)
fullBufs.acquire(n);
while (!m_stop) {
fullBufs.acquire(); // wait fo full buffer
QVector<double> dataPackage(BufferSize);
double seq=bufNo;
if (curBuf==1)
for (int i=0;i<BufferSize;i++){
dataPackage[i]=buffer2[i]; // copy data from full buffer
}
else
for (int i=0;i<BufferSize;i++){
dataPackage[i]=buffer1[i];
}
for (int k=0;k<BufferSize;k++) {
vectorQpointFbufferData[k]=QPointF(x,dataPackage[k]);
}
emptyBufs.release(); // release a buffer
QVariant variantBufferData;
variantBufferData.setValue(vectorQpointFbufferData);
emit newValue(variantBufferData,seq); // send data to main thread
}
quit();
}
当子线程的缓存收集了500个数据时,数据将输入到QVector
中并发送到主线程,并每隔20ms直接分配给qchartview中的线系列以进行绘制。我使用QtChart
绘制数据图表。
void MainWindow::onthreadB_newValue(QVariant bufferData, double bufNo) {
// Analysis of QVariant data
CH1.hardSoftDataPointPackage = bufferData.value<QVector<QPointF>>();
if (ui->CH1_Source->currentIndex()==0) {
for (int p = 0;p<CH1.hardSoftDataPointPackage.size();p++) {
series_CH3->append(CH1.hardSoftDataPointPackage[p]);
}
}
}
主线程中有一个计时器,间隔为20ms,并且有一个双倍的时间(时间=时间+1),它控制着X轴。
void MainWindow::drawAxis(double time) {
// dynamic draw x axis
if (time<100) {
axisX->setRange(0, TimeBase/(1000/FrameRate) * 10);
// FrameRate=50
} else {
axisX->setRange(time-TimeBase/(1000/FrameRate) * 10, time);
}
}
但是,当我运行程序时,存在一个问题,每次子线程将数据发送到主线程时,主线程都会卡住几秒钟,而绘图也会卡住几秒钟。我在主线程中添加了一条曲线,以从主线程获取数据,发现两条曲线将同时卡住。我不知道如何解决这个问题。
此外,我希望主线程在20ms内均匀地从子线程中提取数据,而不是一次绘制所有点。
答案 0 :(得分:2)
您的主线程卡住了,因为您一次复制(添加到系列中)很多数据。相反,您可以在不发出信号的情况下在线程实例内部收集所有数据。每20毫秒从主线程获取少量收集的数据。
类似这样的东西:
while(!m_stop)
{
...
//QVariant variantBufferData;
//variantBufferData.setValue(vectorQpointFbufferData);
//emit newValue(variantBufferData,seq);//send data to main thread
//instead this just store in internal buffer
m_mutex.lock();
m_internalBuffer.append(vectorQpointFbufferData);
m_mutex.unlock();
}
读取方法
QVector<QPointF> QThreadShow::takeDataPiece()
{
int n = 4;
QVector<QPointF> piece;
piece.reserve(n);
m_mutex.lock();
for (int i = 0; i < n; i++)
{
QPointF point = m_internalBuffer.takeFirst();
piece.append(point);
}
m_mutex.unlock();
return piece;
}
并且在主线程中读取超时插槽
void MainWindow::OnDrawTimer()
{
QVector<QPointF> piece = m_childThread.takeDataPiece();
//add to series
...
//drawAxis
...
}