有時候技術(shù)人員之間的差異微乎其微,但就是這微乎其微的差異積少成多,讓我們與大牛之間的距離越來越遠,當(dāng)你開始在意這些細節(jié)而不是只關(guān)注成長的速度的時候,時間會告訴你當(dāng)前版本的答案,技術(shù)的積累會產(chǎn)生難以想象的質(zhì)變。大鵬一日同風(fēng)起,然后一直起!起!起?。ǔ哆h了...回歸主題)。
會用和看懂是兩個概念,假如你不趕時間的話,我愿用我蹩腳的解釋,帶你去看看作者的匠心獨具。先上第一段熱乎的代碼:
語言的盡頭并不是C語言,機器無法執(zhí)行一段C代碼,她需要經(jīng)編譯,匯編等等操作最終形成可執(zhí)行的機器碼,當(dāng)然我們是看不懂的,所以我們要理解,C語言首先要變成匯編代碼,那么一條語句就可能編程好幾句。
當(dāng)你從裸機編程切換到OS調(diào)度機制的時候,本質(zhì)上來講比單純的裸機,CPU需要執(zhí)行的代碼更多更復(fù)雜了,機器的性能相對是降低了,為了盡量降低這種額外的開銷,于是就出現(xiàn)了開局default的操作,這完全是站在機器的角度上選擇結(jié)果,軟件少一次的case判斷,變成匯編語言就是可以少執(zhí)行好幾條語句,節(jié)省掉多個機器周期。
接下來:讓我們看一下兩種運行任務(wù)的方式:
//運行任務(wù)
#define RunTask(TaskName,TaskID)
do
{
if (timers[TaskID]==0)
{
TASK d=TaskName();
while(timers[TaskID]!=d)
timers[TaskID]=d;
}
} while(0);
//運行任務(wù),前面的任務(wù)優(yōu)先保證執(zhí)行
#define RunTaskA(TaskName,TaskID)
do
{
if (timers[TaskID]==0)
{
TASK d=TaskName();
while(timers[TaskID]!=d)
timers[TaskID]=d;
continue;
}
} while(0);
先看下任務(wù)是如何運行的,先判斷該任務(wù)對應(yīng)的阻塞時間是否到達:
1. 沒到達的情況下,不運行任務(wù),結(jié)束執(zhí)行。
2.時間到,timers倒計時為0,執(zhí)行任務(wù),并返回阻塞時間,第一個細節(jié)操作來了,先判斷timers是否等于返回的阻塞時間,如果不等于則進行賦值,這里是不是多此一舉,不用判斷直接賦值多好,去掉while判斷。你能這么想是因為你站在程序員的角度上,換一個角度,你站在機器的角度上來考慮問題,while判斷和賦值操作的運行時間,假定賦值操作需要更多的執(zhí)行時間開銷,那么加一條while判斷,再相等的情況下,是否就不需要執(zhí)行賦值操作了,可以節(jié)省更多的操作時間,二當(dāng)需要賦值的情況下,可能也就加一條簡單的判斷操作,我是這樣的理解的,當(dāng)然也可能不對,只是給你提供一條思路。
對比任務(wù)和函數(shù)的區(qū)別:函數(shù)的返回值一般給到的是變量,作為函數(shù)執(zhí)行的輸出(當(dāng)然是純軟的情況下,有硬件參與的情況下,更多的是硬件對應(yīng)的執(zhí)行動作),任務(wù)的返回值的意義是:阻塞時間,將值記錄到任務(wù)對應(yīng)的timers數(shù)組中,提供給任務(wù)框架進行計時操作。
RunTask和RunTaskA的最大區(qū)別,就是continue的操作,執(zhí)行完任務(wù)后,理論上任務(wù)返回的阻塞時間可以是任意值,當(dāng)返回值為0時,代表著任務(wù)并未阻塞,這個是帶有continue操作的任務(wù)將會重新運行該任務(wù),也就是TaskA優(yōu)先保證執(zhí)行。