首页| 论坛| 消息

标题:Qt多线程数据处理
作者:curiosity
日期:2017-01-15 11:07
内容:

是这样的,我想借助Qt做一个数据融合的任务,初步想法是这样的,除了GUI主线程,还有三个子线程,一个是毫米波雷达数据接收线程(用UDP通信),一个相机图像获取线程,一个对这两个传感器数据进行融合处理的融合线程。
我想要实现在界面上依次点击打开毫米波接收线程和相机图像线程,这个时候两个传感器就开始不断读数了,然后点击融合,开始融合线程。
现在的问题在于,融合线程必须要用到毫米波线程和相机线程的数据,如果采用信号槽的方式不断将毫米波线程和相机线程的数据发给融合线程,如何设置判断条件使得融合线程确实已经完整收到毫米波线程和相机线程的数据了?
另外,我的融合线程处理量比较大,运行比较慢,而两个传感器读数频率比较快,如果用信号槽,不断发送信号给融合线程,融合线程还没处理完,那信号是会阻塞的吗?如果阻塞的话,那融合线程再处理的话就是被阻塞的那一次的数据了,但我想要时刻处理最新的数据,应该如何实现?
如果不用信号槽的话,用QMutex同步的手段是不是可以满足我的功能?
初用Qt多线程,问题比较多,多谢大家了!


#1 [firebolt 01-15 18:09]
你这个应该采用“生产/消费”模型,数据采集线程把采集到的数据放到一个队列里,融合线程从队列中读取数据并处理。队列需要一个或两个条件变量(队列满,队列空),如果队列满,阻塞采集线程,如果队列空阻塞融合线程。数据量大用线程消息不合适。
#2 回 firebolt 的帖子 [curiosity 01-15 19:22]
firebolt:你这个应该采用“生产/消费”模型,数据采集线程把采集到的数据放到一个队列里,融合线程从队列中读取数据并处理。队列需要一个或两个条件变量(队列满,队列空),如果队列满,阻塞采集线程,如果队列空阻塞融合线程。数据量大用线程消息不合适。 (2017-01-15 18:09) 
我之前也想到过用“生产者/消费者”模式,好像要用QWaitCondition来处理是吗?主要是不太熟悉这种用法,看了Qt官方的例子和解释文档之后也是挺懵的。
那如果把采集线程的数据放到一个队列里,队列是用一个数组来存储吗?那这个数组的长度应该多少合适,那我的两个采集线程——毫米波接收线程和相机线程都把数据缓存在各自的队列里是吗?那我的融合线程从这两个队列里取数如何能保证最好能取到最新的数据,因为队列好像是先进先出的吧?
多谢!
#3 回 curiosity 的帖子 [firebolt 01-15 20:06]
curiosity:我之前也想到过用“生产者/消费者”模式,好像要用QWaitCondition来处理是吗?主要是不太熟悉这种用法,看了Qt官方的例子和解释文档之后也是挺懵的。
那如果把采集线程的数据放到一个队列里,队列是用一个数组来存储吗?那这个数组的长度应该多少合适,那我的两个采集线程——毫 .. (2017-01-15 19:22) 
1、Qt本身就有队列模板QQueue,不过你需要对它在封装一下,加入条件变量。
2、如果你对数据顺序不敏感那就不需要队列了,你只需要保存一个最新的副本就行了,还是加入一个条件变量,有新的数据就通知融合线程处理。
#4 [firebolt 01-15 20:33]
我现在做的项目和你这个差不多,我采集线程把DDC信号做FFT后,发送给一个dispatch线程根据设定频率分割给不同的子窗口做显示。我的做法是在dispatch线程里保存一个最新的副本,run函数wait一个条件变量,如果副本发生变化,我就做处理,否则就等待。程序结构大概是这样的。
class TDispatchThread : public QThread
{
public:
void Start();
void Stop();
void dispatch( float *fft, uint32_t length );
protected:
void waitForChange();
void run();
//关闭标志
bool m_close;
//fft 锁
QMutex m_lock;
// 条件变量
QWaitCondition m_wait;
float*m_FFT_Buffer; //buffer used by IF spectrum FFT
bool m_Changed;
};
后面简单的写一下处理过程
// ddc 采集线程调用该方法
void TDispatchThread::dispatch(float * fft , uint32_t length )
{
m_lock.lock();
memcpy(m_FFT_Buffer,fft,length * sizeof(float));
....其它一些操作
m_Changed = true;
//通知所有等待的条件变量
m_wait.wakeAll(); m_lock.unlock();
}
//等待更新信号
void TDispatchThread::waitForChange()
{
m_lock.lock();
while(!m_Changed)
m_wait.wait(&m_lock);
m_lock.unlock();
}
//线程处理过程
void TDispatchThread::run()
{
while(!m_close)
{
//等待新数据
waitForChange();
m_lock.lock();
//加入数据处理过程
m_Changed = false;
&n ..
#5 回 firebolt 的帖子 [curiosity 01-16 10:12]
firebolt:我现在做的项目和你这个差不多,我采集线程把DDC信号做FFT后,发送给一个dispatch线程根据设定频率分割给不同的子窗口做显示。我的做法是在dispatch线程里保存一个最新的副本,run函数wait一个条件变量,如果副本发生变化,我就做处理,否则就等待。程序结构大概是这样的。
class .. (2017-01-15 20:33) 
你好,关于你这个程序我有几个问题想细问一下:
1、你是在DDC采集线程中将TDispacthThread线程类声明一个对象,然后调用该对象的dispatch函数来给m_FFT_Buffer赋值是吧,那这个TDispacthThread线程的开始也是在DDC线程中调用start()函数吗?TDispacthThread线程开始后运行run()函数,等待条件变量,等待到条件变量之后运行数据处理,锁定互斥量m_lock,那这个时候void TDispatchThread::dispatch(float * fft , uint32_t length )函数由于互斥量的作用会被阻塞是吗?那接收线程还在接收数据吗?如果还在接收并不断调用这个函数,那下次数据处理线程释放m_lock时,得到的fft是阻塞前的旧的值吗?
2、我现在是有两个数据接收线程,那我是要在接收线程类里定义两个互斥量、两个条件变量来实现我得到两个线程的数据之后,才开始数据处理的要求吗?
多谢回答了!

<< 1 2 >> (1/2)

回复 发表
主题 版块