好久前寫過一篇相關的推文,當時也是第一次接觸和使用,由于沒有深入的了解和研究, 這段時間一直存在疑惑,趁著這段時間就回顧一下和解決疑惑.
|疑惑
很多知識其實是自學的, 有些知識雖然學了, 但是并沒有認真深入了解. 時間戳的實現往往是使用u32類型的變量在1ms定時中自加,那么:
u32極限值:4294967295 約等于4294967秒 約等于71582分 約等于1193小時 約等于49.7天
從結果就可以看出49.7天后就會溢出, 由此就可以看出時間戳并不能保證唯一性,這就是時間戳最明顯的bug,導致項目不敢使用這個技巧,后來發現好像不對勁, 為啥這么多大佬在用不會出問題,所以就抽空深入研究一下.
|解惑
時間戳: 簡單可以理解為某一時刻的時間點, 并不是常規計算機理解的時間戳(時間戳是指格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至現在的總秒數)!
持續時間:持續時間是指時間間隔的長度,即定義間隔開始和結束的時刻之間的時間距離。
要明確區分常規的概念和特定場景下的概念, 高級語言是可以通過時間戳相減獲取時間間隔與持續時間做對比, 而本文說的時間戳并不是唯一的, 所以直接使用時間戳相減意義并不是很大. 通過觀察可以發現,一個數有最大值, 并且時間間隔又是固定的, 那是不是意味著有規律可循, 由于u32的數太大, 就直接使用u8的數來驗證猜想:
#include"stdio.h" #include"stdint.h" intmain() { uint8_ttick_now=0;//當前的時間戳 uint8_ttick_old=0;//過去的時間戳 uint8_twait=3;//等待的時間 uint8_tdiff=0;//時間差 uint32_tj=0; printf("tick_old:%d,j:%d ",tick_old,j); for(uint32_ti=0;i2000;?i++) ????{ ????????tick_now?=?tick_now?+?1; ????????diff?=?tick_now?-?tick_old; ????????if(diff?==?wait) ????????{ ????????????j++; ????????????tick_old?=?tick_old?+?wait; ????????????printf("tick_old:%d,j:%d ",?tick_old,?j); ????????} ????} ????return?0?; }
結果輸出:
tick_old:0,j:0 tick_old:3,j:1 tick_old:6,j:2 tick_old:9,j:3 tick_old:12,j:4 tick_old:15,j:5 tick_old:18,j:6 tick_old:21,j:7 tick_old:24,j:8 tick_old:27,j:9 tick_old:30,j:10 tick_old:33,j:11 tick_old:36,j:12 tick_old:39,j:13 tick_old:42,j:14 tick_old:45,j:15 tick_old:48,j:16 tick_old:51,j:17 tick_old:54,j:18 tick_old:57,j:19 tick_old:60,j:20 tick_old:63,j:21 tick_old:66,j:22 tick_old:69,j:23 tick_old:72,j:24 tick_old:75,j:25 tick_old:78,j:26 tick_old:81,j:27 tick_old:84,j:28 tick_old:87,j:29 tick_old:90,j:30 tick_old:93,j:31 tick_old:96,j:32 tick_old:99,j:33 tick_old:102,j:34 tick_old:105,j:35 tick_old:108,j:36 tick_old:111,j:37 tick_old:114,j:38 tick_old:117,j:39 tick_old:120,j:40 tick_old:123,j:41 tick_old:126,j:42 tick_old:129,j:43 tick_old:132,j:44 tick_old:135,j:45 tick_old:138,j:46 tick_old:141,j:47 tick_old:144,j:48 tick_old:147,j:49 tick_old:150,j:50 tick_old:153,j:51 tick_old:156,j:52 tick_old:159,j:53 tick_old:162,j:54 tick_old:165,j:55 tick_old:168,j:56 tick_old:171,j:57 tick_old:174,j:58 tick_old:177,j:59 tick_old:180,j:60 tick_old:183,j:61 tick_old:186,j:62 tick_old:189,j:63 tick_old:192,j:64 tick_old:195,j:65 tick_old:198,j:66 tick_old:201,j:67 tick_old:204,j:68 tick_old:207,j:69 tick_old:210,j:70 tick_old:213,j:71 tick_old:216,j:72 tick_old:219,j:73 tick_old:222,j:74 tick_old:225,j:75 tick_old:228,j:76 tick_old:231,j:77 tick_old:234,j:78 tick_old:237,j:79 tick_old:240,j:80 tick_old:243,j:81 tick_old:246,j:82 tick_old:249,j:83 tick_old:252,j:84 tick_old:255,j:85
尋找規律:
//剛開始 tick_old:0,j:0 //第一次溢出 tick_old:255,j:85 tick_old:2,j:86 //第二次溢出 tick_old:254,j:170 tick_old:1,j:171 //第三次溢出 tick_old:253,j:255 tick_old:0,j:256 //第四次溢出 tick_old:255,j:341 tick_old:2,j:342 //第五次溢出 tick_old:254,j:426 tick_old:1,j:427 //第六次溢出 tick_old:253,j:511 tick_old:0,j:512 ...
通過觀察可以發現等待的時間的設定和溢出多少次后再次回到0值是有關系的, 上面設定的等待時間為3就意味著溢出三次就進入下一個循環,同時可以看到每次觸發的時間間隔都是3, 并不會因為溢出而導致出現問題.
注意: 時間間隔只有保證在49.7天內才會正常使用!
所以規避時間溢出BUG 的方法就是對時間戳做減法,直接使用時間戳就必然需要解決時間溢出的BUG!
審核編輯:湯梓紅
-
計算機
+關注
關注
19文章
7167瀏覽量
87139 -
時間戳
+關注
關注
0文章
15瀏覽量
2556
原文標題:技巧|時間戳
文章出處:【微信號:玩轉單片機,微信公眾號:玩轉單片機】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論