好久前寫(xiě)過(guò)一篇相關(guān)的推文,當(dāng)時(shí)也是第一次接觸和使用,由于沒(méi)有深入的了解和研究, 這段時(shí)間一直存在疑惑,趁著這段時(shí)間就回顧一下和解決疑惑.
|疑惑
很多知識(shí)其實(shí)是自學(xué)的, 有些知識(shí)雖然學(xué)了, 但是并沒(méi)有認(rèn)真深入了解. 時(shí)間戳的實(shí)現(xiàn)往往是使用u32類型的變量在1ms定時(shí)中自加,那么:
u32極限值:4294967295 約等于4294967秒 約等于71582分 約等于1193小時(shí) 約等于49.7天
從結(jié)果就可以看出49.7天后就會(huì)溢出, 由此就可以看出時(shí)間戳并不能保證唯一性,這就是時(shí)間戳最明顯的bug,導(dǎo)致項(xiàng)目不敢使用這個(gè)技巧,后來(lái)發(fā)現(xiàn)好像不對(duì)勁, 為啥這么多大佬在用不會(huì)出問(wèn)題,所以就抽空深入研究一下.
|解惑
時(shí)間戳: 簡(jiǎn)單可以理解為某一時(shí)刻的時(shí)間點(diǎn), 并不是常規(guī)計(jì)算機(jī)理解的時(shí)間戳(時(shí)間戳是指格林威治時(shí)間1970年01月01日00時(shí)00分00秒(北京時(shí)間1970年01月01日08時(shí)00分00秒)起至現(xiàn)在的總秒數(shù))!
持續(xù)時(shí)間:持續(xù)時(shí)間是指時(shí)間間隔的長(zhǎng)度,即定義間隔開(kāi)始和結(jié)束的時(shí)刻之間的時(shí)間距離。
要明確區(qū)分常規(guī)的概念和特定場(chǎng)景下的概念, 高級(jí)語(yǔ)言是可以通過(guò)時(shí)間戳相減獲取時(shí)間間隔與持續(xù)時(shí)間做對(duì)比, 而本文說(shuō)的時(shí)間戳并不是唯一的, 所以直接使用時(shí)間戳相減意義并不是很大. 通過(guò)觀察可以發(fā)現(xiàn),一個(gè)數(shù)有最大值, 并且時(shí)間間隔又是固定的, 那是不是意味著有規(guī)律可循, 由于u32的數(shù)太大, 就直接使用u8的數(shù)來(lái)驗(yàn)證猜想:
#include"stdio.h" #include"stdint.h" intmain() { uint8_ttick_now=0;//當(dāng)前的時(shí)間戳 uint8_ttick_old=0;//過(guò)去的時(shí)間戳 uint8_twait=3;//等待的時(shí)間 uint8_tdiff=0;//時(shí)間差 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?; }
結(jié)果輸出:
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
尋找規(guī)律:
//剛開(kāi)始 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 ...
通過(guò)觀察可以發(fā)現(xiàn)等待的時(shí)間的設(shè)定和溢出多少次后再次回到0值是有關(guān)系的, 上面設(shè)定的等待時(shí)間為3就意味著溢出三次就進(jìn)入下一個(gè)循環(huán),同時(shí)可以看到每次觸發(fā)的時(shí)間間隔都是3, 并不會(huì)因?yàn)橐绯龆鴮?dǎo)致出現(xiàn)問(wèn)題.
注意: 時(shí)間間隔只有保證在49.7天內(nèi)才會(huì)正常使用!
所以規(guī)避時(shí)間溢出BUG 的方法就是對(duì)時(shí)間戳做減法,直接使用時(shí)間戳就必然需要解決時(shí)間溢出的BUG!
審核編輯:湯梓紅
-
計(jì)算機(jī)
+關(guān)注
關(guān)注
19文章
7360瀏覽量
87632 -
時(shí)間戳
+關(guān)注
關(guān)注
0文章
15瀏覽量
2575
原文標(biāo)題:技巧|時(shí)間戳
文章出處:【微信號(hào):玩轉(zhuǎn)單片機(jī),微信公眾號(hào):玩轉(zhuǎn)單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論