在系统的计时计数过程中,大多采用无符号数来表示。一个无符号数总有一个最大表示范围,比如unsigned int 的最大表示数为2的32次方-1 4294967295,此时如果继续增加则回绕(wrap around)为0.此时就涉及到一个正确比较的问题,下面以linux中的节拍记录变量jiffies为例说明这个问题,jiffies记录开机以来发生的节拍数,每次时钟中断程序都会增加这个值(每秒增加的值为HZ)。系统中的很多函数就依赖与当前的jiffies值比较来决定时间片是否用完,某个等待是否超时……
看一个回绕的例子:
unsigned long timeout = jiffies + HZ/2; //0.5秒后超时
……
if(timeout > jiffies)
printf("No timeout!");
else
printf("Timeout!");
当发生回绕的情况下我们发现上面的判断是正好相反的。因此在可能发生回绕的场景下,我们不能采用如上的大于小于判断方法。
linux中的实现克服了这个问题:
#define time_after(a,b) ((long)(b) - (long)(a) < 0)
请思考为什么这里的减操作使用的是有符号数来进行?
未完待续