::本篇文章是论述上一篇"基于选择重传ARQ传输协议的数据重传机制方案设计"中定时器的实现
错误更正:
1.背景
在本项目中,由于每个硬件传感器在软件系统中都对应一个传感器对象,数据传输以及重传操作是针对每个传感器对象而言的,所以,每个对象应该对应一个定时器(该定时器是针对每个对象所拥有的重传队列的,并不是针对要接收的下一包,这点很重要,这是两种不同的思维方式,个人认为第一种方案比较好)。针对重传队列的定时器在超时后之后将重传队列发送给对应的传感器,而当接收到数据之后就会重置定时器(即将发送重传队列的时间往后推迟),当一次采集数据的小包都接收完成之后(假设中间掉了几包,如果没有掉包就会立即取消当前定时器并下发重传队列),定时器不会再被重置。这样,过了一段时候后,定时器超时,然后将重传队列发送给发送方。发送方接收到重传队列之后,检测对应bite位,然后重传相应小包数据。
2.面临的关键问题
1. 数据重传模块是工作在幕后,没有跟窗口相关联,所以不能用MFC提供的非常方便的ontimer定时器。
2. 由于每个传感器对象在重传的时候时延不一样,所以不能用一个统一的定时器,必须给每个对象都设置一个单独的定时器。
3. C++类中的线程处理函数必须为static,这使得线程处理函数不能使用类中的非static成员变量。线程处理函数之所以需要是static是因为:设某函数原型为LRESULT ThreadProc(LPVOID pv);若为非静态成员函数,编译时自动展开为 ThreadProc(pClass-> this, pv);与线程函数调用不相符。所以必须使用全局函数或类静态成员函数。
4. 定时器的超时处理函数也必须为static,所以不管你设置多少个定时器,最终定时器的处理函数一样。
3.解决方案
首先对于对于第一个问题,我们使用windows API SetTimer()来自定义定时器。
其次,在开启一个线程时,将当前对象的this指针传递给线程处理函数,在线程处理函数中使用this指针来调用非static的函数并给该对象设置定时器。
最后,我们在超时处理函数中建立一个map,用来记录定时器ID跟相应对象的关系。这样当一个定时器超时后,我们根据ID就能找到对应的对象,从而对该对象进行操作。
下面我们来看一看具体实现代码:
工程下载地址: