您好,登錄后才能下訂單哦!
今天小編給大家分享一下golang墻上時鐘與單調(diào)時鐘如何實現(xiàn)的相關(guān)知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
墻上時鐘也稱為墻上時間。大多是1970年1月1日(UTC)以來的秒數(shù)和毫秒數(shù)。
墻上時間可以和NTP(Network Time Protocal,網(wǎng)絡(luò)時間協(xié)議)同步,但是如果本地時鐘遠遠快于NTP服務(wù)器,則強制重置之后會跳到先前某個時間點。(這里不是很確定,猜測是如果時間差的不多,則調(diào)整石英晶體振蕩器的頻率,慢慢一致。如果差很多,則強行一致)
機器大多有自己的石英晶體振蕩器,并將其作為計時器。單調(diào)時鐘的絕對值沒有任何意義,根據(jù)操作系統(tǒng)和語言的不同,單調(diào)時鐘可能在程序開始時設(shè)為0、或在計算機啟動后設(shè)為0等等。但是通過比較同一臺計算機上兩次單調(diào)時鐘的差,可以獲得相對準確的時間間隔。
type Time struct { // wall and ext encode the wall time seconds, wall time nanoseconds, // and optional monotonic clock reading in nanoseconds. // // From high to low bit position, wall encodes a 1-bit flag (hasMonotonic), // a 33-bit seconds field, and a 30-bit wall time nanoseconds field. // The nanoseconds field is in the range [0, 999999999]. // If the hasMonotonic bit is 0, then the 33-bit field must be zero // and the full signed 64-bit wall seconds since Jan 1 year 1 is stored in ext. // If the hasMonotonic bit is 1, then the 33-bit field holds a 33-bit // unsigned wall seconds since Jan 1 year 1885, and ext holds a // signed 64-bit monotonic clock reading, nanoseconds since process start. wall uint64 ext int64 ... }
wall和ext共同記錄了時間,但是分為兩種情況,一種是沒有記錄單調(diào)時鐘(比如是通過字符串解析得到的時間),另一種是記錄了單調(diào)時鐘(比如通過Now)。
wall的第一位是一個標記位
如果為1,則表示記錄了單調(diào)時鐘。則wall的2-34(閉區(qū)間)位記錄了從1885-1-1到現(xiàn)在的秒數(shù),最后30位記錄了納秒數(shù)。而ext記錄了從程序開始運行到現(xiàn)在經(jīng)過的單調(diào)時鐘數(shù)。
如果為0,則表示沒有記錄單調(diào)時鐘。則wall的2-34(閉區(qū)間)位全部為0(那最后30位是啥?)。而ext記錄了從1-1-1到現(xiàn)在經(jīng)過的秒數(shù)。
這里比較關(guān)鍵的代碼是第914行的runtimeNano() - startNano
。startNano
的含義還是直接上代碼比較明了。
var startNano = 0 func init(){ startNano = runtimeNano() }
runtimeNano()
是調(diào)用了匯編,獲取了操作系統(tǒng)當前的單調(diào)時鐘。前面說過,單調(diào)時鐘的絕對值沒有什么意義。因此這里將兩個時間相減,得到了從程序開始到現(xiàn)在的單調(diào)時鐘。
然后看一下Sub
func (t Time) Sub(u Time) Duration { if t.wall&u.wall&hasMonotonic != 0 { te := t.ext ue := u.ext d := Duration(te - ue) if d < 0 && te > ue { return maxDuration // t - u is positive out of range } if d > 0 && te < ue { return minDuration // t - u is negative out of range } return d } d := Duration(t.sec()-u.sec())*Second + Duration(t.nsec()-u.nsec()) // Check for overflow or underflow. switch { case u.Add(d).Equal(t): return d // d is correct case t.Before(u): return minDuration // t - u is negative out of range default: return maxDuration // t - u is positive out of range } }
這里我們只需要關(guān)注2-13行即可。除去了范圍檢查,這里的主要邏輯就是兩個Time的ext相減。而ext又都代表了單調(diào)時鐘,所以最后返回的是單調(diào)時鐘的差值。
以上就是“golang墻上時鐘與單調(diào)時鐘如何實現(xiàn)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。