socket read time out解决方法_time_after方法对jiffies回绕问题的解决
前言:
最近在啃《 Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)》,看到第四章CFS時(shí)候,讀了幾遍沒太理清這一小節(jié)到思路,看到40頁(yè)這么一句話:“如果這里所討論的定時(shí)器節(jié)拍對(duì)你來說很陌生,快先去看看第十一章再說。因?yàn)檫@點(diǎn)正是引入CFS的唯一原因”。
于是就先讀了十一章:定時(shí)器和時(shí)間管理,其中提到了linux使用unsigned long jiffies,一個(gè)無符號(hào)的long記錄節(jié)拍的數(shù)量,如果時(shí)鐘頻率是1000hz,32位的系統(tǒng)上。這個(gè)值47.9天就會(huì)溢出。如果溢出之前設(shè)定了定時(shí)器,溢出以后jiffies作為無符號(hào)數(shù)的值會(huì)小于超時(shí)時(shí)間的值,如果使用current > timeout 就會(huì)導(dǎo)致錯(cuò)誤的判斷。
但是,操作系統(tǒng)提供了宏time_after(current,timeout)可以避免這個(gè)問題。看到這個(gè)宏的定義,剛開始沒有立刻看懂,上網(wǎng)查了一些解析也說的不是很簡(jiǎn)潔。自己想明白以后,覺得挺有意思,就打算記錄一下。希望如果有人在上網(wǎng)查這個(gè)的時(shí)候,有機(jī)會(huì)查到我這種思路,看下是不是比較容易理解。
轉(zhuǎn)載:
time_after防止回繞原理
正文:
首先看下這個(gè)宏的定義:
#define time_after(current,timeout) ((long)(timeout) - (long)(current)< 0)WTF?只是把無符號(hào)輸轉(zhuǎn)化成有符號(hào)數(shù)就能解決這個(gè)問題嗎?這是什么原理。。。
下面用我覺得比較簡(jiǎn)單的思路分析一下這個(gè)問題。
首先我們用4位的數(shù)字來舉例比較簡(jiǎn)單。
問題是這樣發(fā)生的:假設(shè)當(dāng)前的時(shí)間是13(1101),設(shè)定一個(gè)節(jié)拍以后超時(shí),所以超時(shí)時(shí)間就是14(1110).然后,過了3個(gè)節(jié)拍以后,當(dāng)前時(shí)間變成了current = 13 + 3 = 1101 + 0011 = 10000 = 0000 = 0,這個(gè)時(shí)候雖然超時(shí)了,但是(current =0) < (timout=14),如果代碼使用if(current > timeout)來判斷是否超時(shí)就會(huì)判斷錯(cuò)誤。
那么如果把這兩個(gè)數(shù)強(qiáng)制轉(zhuǎn)化成有符號(hào)數(shù),是不是就能正確判斷了呢?
計(jì)算機(jī)使用補(bǔ)碼存儲(chǔ)數(shù)字,負(fù)數(shù)原碼轉(zhuǎn)補(bǔ)碼是+1以后取反,所以timeout = 1110 轉(zhuǎn)成負(fù)數(shù)源碼就是-1再取反就是(1101取反)1010 也就是-2,current是0,這個(gè)時(shí)候current = 0 > timeout= -2 是成立的。
但是我的疑問是,這只能保證回繞的時(shí)候,timeout - current < 0,那不回繞呢?而且這只測(cè)試了回繞的一種情況,不能證明所有的回繞都滿足timeout - current < 0吧,怎么證明這個(gè)一定成立呢?
time_after防止回繞原理 這個(gè)帖子給了我思路,但是感覺他說的還是不夠簡(jiǎn)潔。帖子里說的內(nèi)容其實(shí)可以用一個(gè)坐標(biāo)系圖簡(jiǎn)單的表達(dá)出來。其中x軸是無符號(hào)數(shù)的取值,y軸是對(duì)應(yīng)的有符號(hào)數(shù)的取值。首先我們?cè)趀xcel中列出4位數(shù)的xy所有取值,然后生成曲線圖,就很明白了:
current 與 timout 的取值總共分以下4中情況:
1. current 和 timout 都在正數(shù)單調(diào)遞增的部分:
這種情況下 很明顯 timeout - current < 0。
2. current 和 timout 都在負(fù)數(shù)單調(diào)遞增的部分:
這種情況下同情況1。
3. current 為負(fù)數(shù) 和 timout 為正數(shù):
這種情況下 timeout - current= 正數(shù)-負(fù)數(shù) ,應(yīng)該是一個(gè)正數(shù)啊,怎么會(huì)小于0呢?
問題是最終結(jié)果的取值相當(dāng)于兩個(gè)點(diǎn)y軸絕對(duì)值相加,如果兩個(gè)點(diǎn)x坐標(biāo)距離小于8,那么這兩個(gè)點(diǎn)y的絕對(duì)值之和一定大于8,而大于8的無符號(hào)數(shù)轉(zhuǎn)化成有符號(hào)數(shù)是一個(gè)負(fù)數(shù)。所以timeout - current <0
4. urrent 為正數(shù) 和 timout 為負(fù)數(shù):
這種情況下 同情況3,不再贅述。
假設(shè)在32位系統(tǒng)使用32位來保存jiffies,1000hz的處理器,想要讓兩個(gè)點(diǎn)的距離超過0xffff,相當(dāng)于設(shè)置一個(gè)20多天以后超時(shí)的定時(shí)任務(wù)。這種情況下timeout - current <0才不成立,而內(nèi)核肯定不會(huì)使用這么長(zhǎng)的超時(shí)時(shí)間,所以可以認(rèn)為timeout - current <0在所有情況下都是成立的。
這樣就很清晰的把這個(gè)原理表達(dá)清楚了。
總結(jié):
第十一章總算是看完了,后邊回到第四章在好好理解一下,希望能有新的收獲吧~~
最后,讓我們保持獨(dú)立思考,不卑不亢。長(zhǎng)成自己想要的樣子! (引用自 我非常喜歡的B站up主 ”獨(dú)立菌兒“->猛戳鏈接<-的口頭禪)
總結(jié)
以上是生活随笔為你收集整理的socket read time out解决方法_time_after方法对jiffies回绕问题的解决的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: saas物资管理界面设计_大型物流企业都
- 下一篇: 哈尔滨看无精子症最好的医院推荐