时间精度二三事

场景:中标麒麟系统,网络传输情形,A和B通信,A向B发送原始数据(50ms发送一次数据,1s发送20个数据),B进行数据处理,B把处理后的数据发送给A。

精度要求:要求收到的数据帧频一致,也就是每50ms收到一个数据。

前提:因为我只负责B的开发,由于实验条件,没做过网络测试,从A收数据是否帧频稳定?所以假定A可以精确的50ms发一次数据。

过程:

阶段1(历史代码做法):代码使用QT c++开发,收到数据后调用一个全局线程进行计算,线程类负责计算并发送。反馈帧频不稳。

阶段2:考虑可以设置一个固定的时间长度t(t<50ms,处理时间理想指标),收到数据时记下当前时间t1,计算完毕取当前时间t2,(t2-t1)为计算时间,t-(t2-t1)为线程睡眠时间,保证对齐。但是发现t<(t2-t1),也就说计算过程远超过50ms(处理过程时间过长)。这样就没办法通过线程等待达到时间对齐的效果。

阶段3:将计算和发送分开到两个线程,计算线程从50ms计算一次数据变为1s计算一次,发送线程50ms取一次数据发送。(消费者,生产者)线程通过在槽函数里启动,槽函数通过定时器connect,但是经测试发现,当程序运行一段时间后,槽函数被调用的时间间隔从50ms慢慢变大。同时从槽函数启动线程到线程运行起来的时间也慢慢变大。猜测:connect就是启动了一个新的线程来执行槽函数。

阶段4:考虑到发送数据的时间很短(以ms为度量单位),测试整个过程0ms或1ms。所以去掉发送线程,直接在槽函数中发送数据。在槽函数调用时记时间t1,发送语句执行后记时间t2. 经测试,t1与t2大部分时间都相同,偶尔相差1ms。而不同的数据t1的时间差也基本上是50ms,也会出现51ms,49ms,但是比较少。为了让发送过程的时间长度固定,依旧采用阶段2中线程等待的方式。最终可以保证发送过程的时间固定。但是由于网络传输数据的时间不确定性。严格意义上讲还是不满足要求的,因为B收到数据的帧频依然可能是不稳定的,因为A到B到A过程=A发送的网络传输过程+B收据到发送数据(很短,但是可能不为0,ms级别)+B发送数据的网络传输过程。

总结:

  1. connect是否调用线程来执行槽函数?
  2. 槽函数绑定的定时器时间间隔为t,那么如果槽函数处理过程的时间大于t,会阻塞,就不满足t ms时间调用一次槽函数。
  3. QTimer的灵敏度跟操作系统有关,即便是支持ms级别的unix(linux),QTimer说明中Qt::TimerType 的Qt::PreciseTimer(使用setTimerType设置)也只是精确计时器试图保持毫秒精度。

你可能感兴趣的:(qt,c++)