六、采集/反控调度系统设计
在第一部分,我们提到了数据采集所面临的问题。稳定、并发、时延少、不串码,是调度系统需要解决的问题。
串行读写是最稳定的一种读写方式。遍历设备,把每台设备需要采集的命令发送,得到回复之后,再转到下一台设备。这种方式的缺点是速度慢。如果设备数量大、因子多,某台设备的响应速度慢,那么一个采集循环的时间就会很长。
另一种方式是每一个链路配一个线程,因为不同链路是可以并行读写的。这里需要考虑多设备共用串口的问题。而最大的问题是,当设备数比较大时,要求的线程数也大,这样的资源耗费是巨大的。
我们采用一个线程,解决多设备采集、反控的调度问题,尽可能做到并行、无需等待。
定义一种这样的结构体:
发送数据 |
发送/接收 |
接收回调函数 |
预期执行时间 |
超时时间 |
建立一个列表,存放上述的结构体。采集定时触发,反控由用户触发,每次触发,都会向列表中插入若干个结构体(如果发现列表中有相同链路相同设备相同数据,则不插入)。采集的预期执行时间较长,反控的预期执行时间较短,甚至直接为0。发送/接收状态一开始为发送。
调度线程是一个循环,隔一段时间执行一次操作。每一次操作,先把列表按预期执行时间进行排序,把最需要执行的放在前面。比较每一项的预期执行时间与当前时间,如果已到预期执行时间,则处理结构体。
如果结构体的状态为发送,检查相同链路是否有未接收的结构体。如果有,则跳过。如果没有,则发送数据。把发送/接收状态改为接收。
如果结构体的状态为接收,尝试接收数据。如果能接收数据,调用回调函数,并删除此结构体。如果接收不到,检查当前时间与超时时间。若未超时,跳过。若超时,把此结构体删除。