本發(fā)明涉及后臺(tái)編譯技術(shù)領(lǐng)域,尤其涉及一種編譯方法和一種編譯系統(tǒng)。
背景技術(shù):
目前,隨著電動(dòng)汽車的快速發(fā)展,對(duì)BMS(電池管理系統(tǒng))的不斷提高,這就使得BMS的開發(fā)越來越復(fù)雜,開發(fā)的復(fù)雜性和成本都劇增。例如,在AUTOSAR(汽車開放系統(tǒng)架構(gòu))中,使用傳統(tǒng)的軟件集成編譯,往往面臨造成系統(tǒng)效率低下、擴(kuò)展性差、開發(fā)周期長(zhǎng)、bug多等的問題。
具體地,基于AUTOSAR的BMS開發(fā),其軟件集成編譯實(shí)現(xiàn)的工作是由開發(fā)人員手工編寫源文件腳本完成的,這一步的工作量相當(dāng)大,會(huì)消耗很長(zhǎng)時(shí)間,而且對(duì)開發(fā)人員技術(shù)要求非常高。而一旦有新的功能,開發(fā)人員必須得重新修改腳本,且花大量時(shí)間進(jìn)行調(diào)試,嚴(yán)重影響開發(fā)效率。
因此,如何提升BMS開發(fā)過程中的軟件集成效率,成為目前亟待解決的技術(shù)問題。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明實(shí)施例提供了一種編譯方法和一種編譯系統(tǒng),旨在解決相關(guān)技術(shù)中BMS開發(fā)過程中的軟件集成效率過低的問題,能夠提升軟件集成效率,降低編譯成本。
第一方面,本發(fā)明實(shí)施例提供了一種編譯方法,包括:實(shí)時(shí)檢測(cè)源文件是否發(fā)生改變;通過正則匹配遍歷所述源文件對(duì)應(yīng)的依賴文件,以確定是否對(duì)所述源文件進(jìn)行重新編譯。
在本發(fā)明上述實(shí)施例中,在通過正則匹配遍歷所述源文件對(duì)應(yīng)的依賴文件的步驟之前,還包括:獲取當(dāng)前系統(tǒng)環(huán)境;根據(jù)所述當(dāng)前系統(tǒng)環(huán)境,重新配置編譯配置信息,以供在需要進(jìn)行重新編譯時(shí)使用所述編譯配置信息;以及將所述編譯配置信息保存在配置文件中。
在本發(fā)明上述實(shí)施例中,實(shí)時(shí)檢測(cè)源文件是否發(fā)生改變的步驟,具體包括:獲取檢測(cè)參數(shù),其中,所述檢測(cè)參數(shù)包括源文件的時(shí)間戳、源文件內(nèi)容的哈希值和原編譯配置信息中的一項(xiàng)或多項(xiàng);以及檢測(cè)所述檢測(cè)參數(shù)是否發(fā)生變化,以確定所述源文件的實(shí)時(shí)變化狀態(tài)。
在本發(fā)明上述實(shí)施例中,所述源文件的數(shù)量為多個(gè),以及通過正則匹配遍歷所述源文件對(duì)應(yīng)的依賴文件的步驟,具體包括:并發(fā)運(yùn)行多個(gè)文件重新編譯的測(cè)試進(jìn)程,以供在需要對(duì)所述源文件進(jìn)行重新編譯時(shí)基于源碼狀態(tài)進(jìn)行文件重新編譯。
在本發(fā)明上述實(shí)施例中,并發(fā)運(yùn)行多個(gè)文件重新編譯的測(cè)試進(jìn)程的步驟,具體包括:初始化多個(gè)工作線程;使用所述多個(gè)工作線程輪詢請(qǐng)求隊(duì)列,以處理文件重新編譯的請(qǐng)求;將處理結(jié)果放置在結(jié)果隊(duì)列中;調(diào)用結(jié)果處理函數(shù)對(duì)所述結(jié)果隊(duì)列進(jìn)行處理。
第二方面,本發(fā)明實(shí)施例提供了一種編譯系統(tǒng),包括:源文件檢測(cè)單元,實(shí)時(shí)檢測(cè)源文件是否發(fā)生改變;依賴匹配單元,通過正則匹配遍歷所述源文件對(duì)應(yīng)的依賴文件,以確定是否對(duì)所述源文件進(jìn)行重新編譯。
在本發(fā)明上述實(shí)施例中,還包括:環(huán)境獲取單元,在所述依賴匹配單元遍歷所述源文件對(duì)應(yīng)的依賴文件之前,獲取當(dāng)前系統(tǒng)環(huán)境;配置單元,根據(jù)所述當(dāng)前系統(tǒng)環(huán)境,重新配置編譯配置信息,以供在需要進(jìn)行重新編譯時(shí)使用所述編譯配置信息;以及保存單元,將所述編譯配置信息保存在配置文件中。
在本發(fā)明上述實(shí)施例中,所述源文件檢測(cè)單元具體用于:獲取檢測(cè)參數(shù),其中,所述檢測(cè)參數(shù)包括源文件的時(shí)間戳、源文件內(nèi)容的哈希值和原編譯配置信息中的一項(xiàng)或多項(xiàng),以及檢測(cè)所述檢測(cè)參數(shù)是否發(fā)生變化,以確定所述源文件的實(shí)時(shí)變化狀態(tài)。
在本發(fā)明上述實(shí)施例中,所述源文件的數(shù)量為多個(gè),以及所述依賴匹配單元具體用于:并發(fā)運(yùn)行多個(gè)文件重新編譯的測(cè)試進(jìn)程,以供在需要對(duì)所述源文件進(jìn)行重新編譯時(shí)基于源碼狀態(tài)進(jìn)行文件重新編譯。
在本發(fā)明上述實(shí)施例中,所述依賴匹配單元具體用于:初始化多個(gè)工作線程,使用所述多個(gè)工作線程輪詢請(qǐng)求隊(duì)列,以處理文件重新編譯的請(qǐng)求,將處理結(jié)果放置在結(jié)果隊(duì)列中,并調(diào)用結(jié)果處理函數(shù)對(duì)所述結(jié)果隊(duì)列處理。
通過以上技術(shù)方案,針對(duì)相關(guān)技術(shù)中的BMS開發(fā)過程中的軟件集成效率過低的問題,在源文件發(fā)生改變時(shí),通過正則匹配遍歷該源文件對(duì)應(yīng)的依賴文件,從而確定是否需要基于源碼狀態(tài)自動(dòng)執(zhí)行文件重新編譯,這樣,當(dāng)確定需要重新編譯時(shí),就能為從源文件起的所有文件實(shí)現(xiàn)自動(dòng)重新編譯,而無需大量人工操作,提升了軟件集成效率,降低了編譯成本。
【附圖說明】
為了更清楚地說明本發(fā)明實(shí)施例的技術(shù)方案,下面將對(duì)實(shí)施例中所需要使用的附圖作簡(jiǎn)單地介紹,顯而易見地,下面描述中的附圖僅僅是本發(fā)明的一些實(shí)施例,對(duì)于本領(lǐng)域普通技術(shù)人員來講,在不付出創(chuàng)造性勞動(dòng)性的前提下,還可以根據(jù)這些附圖獲得其它的附圖。
圖1示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的編譯方法的流程圖;
圖2示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的編譯系統(tǒng)的框圖;
圖3示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的Emake子系統(tǒng)的邏輯架構(gòu)圖;
圖4示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的線程池工作模型的示意圖。
【具體實(shí)施方式】
為了更好的理解本發(fā)明的技術(shù)方案,下面結(jié)合附圖對(duì)本發(fā)明實(shí)施例進(jìn)行詳細(xì)描述。
應(yīng)當(dāng)明確,所描述的實(shí)施例僅僅是本發(fā)明一部分實(shí)施例,而不是全部的實(shí)施例。基于本發(fā)明中的實(shí)施例,本領(lǐng)域普通技術(shù)人員在沒有作出創(chuàng)造性勞動(dòng)前提下所獲得的所有其它實(shí)施例,都屬于本發(fā)明保護(hù)的范圍。
在本發(fā)明實(shí)施例中使用的術(shù)語是僅僅出于描述特定實(shí)施例的目的,而非旨在限制本發(fā)明。在本發(fā)明實(shí)施例和所附權(quán)利要求書中所使用的單數(shù)形式的“一種”、“所述”和“該”也旨在包括多數(shù)形式,除非上下文清楚地表示其他含義。
圖1示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的編譯方法的流程圖。
如圖1所示,本發(fā)明實(shí)施例提供的編譯方法,包括:
步驟102,實(shí)時(shí)檢測(cè)源文件是否發(fā)生改變。
步驟104,當(dāng)確定所述源文件發(fā)生改變時(shí),通過正則匹配遍歷所述源文件對(duì)應(yīng)的依賴文件,以確定是否對(duì)所述源文件進(jìn)行重新編譯。
在上述技術(shù)方案中,在檢測(cè)到源文件發(fā)生改變時(shí),需要進(jìn)一步確定是否對(duì)該源文件進(jìn)行重新編譯,具體來說,需要通過正則匹配遍歷該源文件對(duì)應(yīng)的依賴文件,從而確定是否需要基于源碼狀態(tài)自動(dòng)執(zhí)行文件重新編譯,這樣,當(dāng)確定需要重新編譯時(shí),就能為從源文件起的所有文件實(shí)現(xiàn)自動(dòng)重新編譯,而無需大量人工操作,提升了軟件集成效率,降低了編譯成本。
本實(shí)施例中,執(zhí)行主體為Emake系統(tǒng)。Emake是ECS的后臺(tái)子系統(tǒng),是一款用eyy4.11開發(fā)的控制臺(tái)程序,將控制臺(tái)應(yīng)用程序設(shè)計(jì)為沒有圖形用戶界面,并編譯成獨(dú)立的可執(zhí)行文件??刂婆_(tái)應(yīng)用程序通常從命令行運(yùn)行,同時(shí)在命令提示和運(yùn)行的應(yīng)用程序之間交換輸入和輸出信息。因?yàn)樾畔⒖蓪懭肟刂婆_(tái)窗口并從控制臺(tái)窗口讀取,所以這使控制臺(tái)應(yīng)用程序成為ECS引入持續(xù)集成之服務(wù)器編譯的絕佳途徑,而不必考慮用戶界面。
在本發(fā)明上述實(shí)施例中,在步驟104之前,還包括:獲取當(dāng)前系統(tǒng)環(huán)境;根據(jù)當(dāng)前系統(tǒng)環(huán)境,重新配置編譯配置信息,以供在需要進(jìn)行重新編譯時(shí)使用編譯配置信息;以及將編譯配置信息保存在配置文件中。
本實(shí)施例中,執(zhí)行主體為Emake系統(tǒng),Emake系統(tǒng)在開始工作之前,需要知道當(dāng)前的系統(tǒng)環(huán)境,比如標(biāo)準(zhǔn)庫(kù)在哪里、編譯器的安裝位置在哪里、需要安裝哪些組件等,通過指定編譯配置信息,Emake系統(tǒng)就可以靈活適應(yīng)環(huán)境,編譯出各種環(huán)境都能運(yùn)行的機(jī)器碼等編譯配置信息。這些編譯配置信息保存在一個(gè)叫做project.ini的配置文件之中,它由ESB(Embedded System Build,嵌入式系統(tǒng)構(gòu)建)生成,Emake系統(tǒng)通過讀取這個(gè)配置文件,獲知編譯配置信息。
另外,project.ini配置文件可以考慮到不同系統(tǒng)的差異,并且對(duì)各種編譯配置信息給出了默認(rèn)值,如果用戶的編譯環(huán)境比較特別,或者有一些特定的需求,也可以手動(dòng)向project.ini提供參數(shù)。
在本發(fā)明上述實(shí)施例中,步驟102具體包括:獲取檢測(cè)參數(shù),其中,檢測(cè)參數(shù)包括源文件的時(shí)間戳、源文件內(nèi)容的哈希值和原編譯配置信息中的一項(xiàng)或多項(xiàng);以及檢測(cè)檢測(cè)參數(shù)是否發(fā)生變化,以確定源文件的實(shí)時(shí)變化狀態(tài)。
Emake系統(tǒng)可通過文件的時(shí)間戳來判斷文件是否需要進(jìn)行重新編譯,當(dāng)文件版本回滾后或編譯參數(shù)變更后,Emake系統(tǒng)不會(huì)對(duì)文件再次進(jìn)行編譯。
另外,除了使用文件的時(shí)間戳,還可以基于文件內(nèi)容的哈希值以及編譯參數(shù)作為增量編譯的判斷標(biāo)準(zhǔn),這樣,增量編譯的準(zhǔn)確性會(huì)更高。
在本發(fā)明上述實(shí)施例中,源文件的數(shù)量為多個(gè),以及步驟104具體包括:并發(fā)運(yùn)行多個(gè)文件重新編譯的測(cè)試進(jìn)程,以供在需要對(duì)所述源文件進(jìn)行重新編譯時(shí)基于源碼狀態(tài)進(jìn)行文件重新編譯。
將程序以及依賴庫(kù)從源碼狀態(tài)進(jìn)行編譯,解決了c或c++程序因編譯選項(xiàng)、操作系統(tǒng)平臺(tái)或庫(kù)文件版本不同而造成的兼容性問題。
在本發(fā)明上述實(shí)施例中,并發(fā)運(yùn)行多個(gè)文件重新編譯的測(cè)試進(jìn)程的步驟,具體包括:初始化多個(gè)工作線程;使用多個(gè)工作線程輪詢請(qǐng)求隊(duì)列,以處理文件重新編譯的請(qǐng)求;將處理結(jié)果放置在結(jié)果隊(duì)列中;調(diào)用結(jié)果處理函數(shù)對(duì)結(jié)果隊(duì)列進(jìn)行處理。
其中,Emake系統(tǒng)使用易語言的Queue(隊(duì)列)來實(shí)現(xiàn)線程同步。
圖2示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的編譯系統(tǒng)的框圖。
如圖2所示,本發(fā)明實(shí)施例提供的編譯系統(tǒng)200,包括:源文件檢測(cè)單元202和依賴匹配單元204。
其中,源文件檢測(cè)單元202用于實(shí)時(shí)檢測(cè)源文件是否發(fā)生改變;依賴匹配單元204用于當(dāng)確定所述源文件發(fā)生改變時(shí),通過正則匹配遍歷所述源文件對(duì)應(yīng)的依賴文件,以確定是否對(duì)所述源文件進(jìn)行重新編譯。
本實(shí)施例中,執(zhí)行主體為Emake系統(tǒng)。Emake是ECS的后臺(tái)子系統(tǒng),是一款用eyy4.11開發(fā)的控制臺(tái)程序,將控制臺(tái)應(yīng)用程序設(shè)計(jì)為沒有圖形用戶界面,并編譯成獨(dú)立的可執(zhí)行文件??刂婆_(tái)應(yīng)用程序通常從命令行運(yùn)行,同時(shí)在命令提示和運(yùn)行的應(yīng)用程序之間交換輸入和輸出信息。因?yàn)樾畔⒖蓪懭肟刂婆_(tái)窗口并從控制臺(tái)窗口讀取,所以這使控制臺(tái)應(yīng)用程序成為ECS引入持續(xù)集成之服務(wù)器編譯的絕佳途徑,而不必考慮用戶界面。
在上述技術(shù)方案中,在檢測(cè)到源文件發(fā)生改變時(shí),需要進(jìn)一步確定是否對(duì)該源文件進(jìn)行重新編譯,具體來說,需要通過正則匹配遍歷該源文件對(duì)應(yīng)的依賴文件,從而確定是否需要基于源碼狀態(tài)自動(dòng)執(zhí)行文件重新編譯,這樣,當(dāng)確定需要重新編譯時(shí),就能為從源文件起的所有文件實(shí)現(xiàn)自動(dòng)重新編譯,而無需大量人工操作,提升了軟件集成效率,降低了編譯成本。
在本發(fā)明上述實(shí)施例中,還包括:環(huán)境獲取單元206,在依賴匹配單元遍歷所述源文件對(duì)應(yīng)的依賴文件之前,獲取當(dāng)前系統(tǒng)環(huán)境;配置單元208,根據(jù)當(dāng)前系統(tǒng)環(huán)境,重新配置編譯配置信息,以供在需要進(jìn)行重新編譯時(shí)使用編譯配置信息;以及保存單元210,將編譯配置信息保存在配置文件中。
Emake系統(tǒng)在開始工作之前,需要知道當(dāng)前的系統(tǒng)環(huán)境,比如標(biāo)準(zhǔn)庫(kù)在哪里、編譯器的安裝位置在哪里、需要安裝哪些組件等,通過指定編譯配置信息,Emake系統(tǒng)就可以靈活適應(yīng)環(huán)境,編譯出各種環(huán)境都能運(yùn)行的機(jī)器碼等編譯配置信息。這些編譯配置信息保存在一個(gè)叫做project.ini的配置文件之中,它由ESB生成,Emake系統(tǒng)通過讀取這個(gè)配置文件,獲知編譯配置信息。
另外,project.ini配置文件可以考慮到不同系統(tǒng)的差異,并且對(duì)各種編譯配置信息給出了默認(rèn)值,如果用戶的編譯環(huán)境比較特別,或者有一些特定的需求,也可以手動(dòng)向project.ini提供參數(shù)。
在本發(fā)明上述實(shí)施例中,源文件檢測(cè)單元202具體用于:獲取檢測(cè)參數(shù),其中,檢測(cè)參數(shù)包括源文件的時(shí)間戳、源文件內(nèi)容的哈希值和原編譯配置信息中的一項(xiàng)或多項(xiàng),以及檢測(cè)檢測(cè)參數(shù)是否發(fā)生變化,以確定源文件的實(shí)時(shí)變化狀態(tài)。
Emake系統(tǒng)可通過文件的時(shí)間戳來判斷文件是否需要進(jìn)行重新編譯,當(dāng)文件版本回滾后或編譯參數(shù)變更后,Emake系統(tǒng)不會(huì)對(duì)文件再次進(jìn)行編譯。
另外,ECS除了使用文件的時(shí)間戳,還可以基于文件內(nèi)容的哈希值以及編譯參數(shù)作為增量編譯的判斷標(biāo)準(zhǔn),這樣,增量編譯的準(zhǔn)確性會(huì)更高。
在本發(fā)明上述實(shí)施例中,源文件的數(shù)量為多個(gè),以及依賴匹配單元204具體用于:并發(fā)運(yùn)行多個(gè)文件重新編譯的測(cè)試進(jìn)程,以供在需要對(duì)所述源文件進(jìn)行重新編譯時(shí)基于源碼狀態(tài)進(jìn)行文件重新編譯。
在本發(fā)明上述實(shí)施例中,依賴匹配單元204具體用于:初始化多個(gè)工作線程,使用多個(gè)工作線程輪詢請(qǐng)求隊(duì)列,以處理文件重新編譯的請(qǐng)求,將處理結(jié)果放置在結(jié)果隊(duì)列中,并調(diào)用結(jié)果處理函數(shù)對(duì)結(jié)果隊(duì)列處理。
圖3示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的Emake子系統(tǒng)的邏輯架構(gòu)圖。
如圖3所示,Emake子系統(tǒng)是ECS的后臺(tái)子系統(tǒng),是一款用eyy4.11開發(fā)的控制臺(tái)程序,將控制臺(tái)應(yīng)用程序設(shè)計(jì)為沒有圖形用戶界面,并編譯成獨(dú)立的可執(zhí)行文件。
在應(yīng)用層,控制臺(tái)應(yīng)用程序通常從控制臺(tái)命令處理集的命令行運(yùn)行,在請(qǐng)求接入后,對(duì)該請(qǐng)求的命令、協(xié)議進(jìn)行解析,并調(diào)用功能處理模塊進(jìn)行服務(wù)定位、資源調(diào)度等控制調(diào)度,最后,使用應(yīng)用邏輯進(jìn)行應(yīng)用處理,得到系統(tǒng)輸出,其中,系統(tǒng)輸出包括過程日志的輸出和結(jié)果報(bào)表輸出。
其中,功能處理模塊具有編譯管理、目標(biāo)生成管理、靜態(tài)檢測(cè)處理、并發(fā)控制、打包處理和單元測(cè)試處理的功能,其中,編譯管理的模塊連接至依賴引擎。
綜上,在應(yīng)用層,控制臺(tái)應(yīng)用程序通常從控制臺(tái)命令處理集的命令行運(yùn)行,同時(shí)在命令提示和運(yùn)行的應(yīng)用程序之間交換輸入和輸出信息。因?yàn)樾畔⒖蓪懭肟刂婆_(tái)窗口并從控制臺(tái)窗口讀取,所以這使控制臺(tái)應(yīng)用程序成為ECS引入持續(xù)集成之服務(wù)器編譯的絕佳途徑,而不必考慮用戶界面。
其中,Emake子系統(tǒng)的內(nèi)存處理機(jī)制概述如下:
Emake子系統(tǒng)的內(nèi)存處理機(jī)制采用一款高效、靈活、跨平臺(tái)的內(nèi)存池實(shí)現(xiàn),其中,內(nèi)存被劃分為節(jié)點(diǎn)(node)和切片(slice),node為一大塊內(nèi)存,slice為node上的小片內(nèi)存,從內(nèi)存池中申請(qǐng)的每一個(gè)內(nèi)存都屬于一個(gè)slice。每一個(gè)內(nèi)存池實(shí)例里的slice的大小都是一樣的,所以這個(gè)內(nèi)存池更像對(duì)象池?;谠搩?nèi)存池,可實(shí)現(xiàn)一款更加靈活的可以從中申請(qǐng)不同尺寸內(nèi)存的內(nèi)存池。
具體來說,可用的node鏈接成一個(gè)鏈表,可用的slice也鏈接成一個(gè)鏈表。當(dāng)從內(nèi)存池中申請(qǐng)內(nèi)存時(shí),首先檢查是否有空閑的slice,如果有,則取出一個(gè),如果沒有,就檢查最近申請(qǐng)的node里是否還有從未使用過的切片。
如果最近申請(qǐng)的node里有從未使用過的slice,那么取出一個(gè),如果沒有,則將這個(gè)node添加到node鏈表的頭部,再申請(qǐng)一個(gè)新node,并從中取出一個(gè)slice,并返回。這樣,在釋放內(nèi)存時(shí),僅需要將slice插入到空閑的slice鏈表頭部。
上述內(nèi)存池被組織為樹狀結(jié)構(gòu)。當(dāng)創(chuàng)建一個(gè)內(nèi)存池時(shí),可以為其指定父內(nèi)存池,在調(diào)用elr_mpl_create(創(chuàng)建函數(shù))時(shí)使用父內(nèi)存池的指針作為第一個(gè)參數(shù)即可。
當(dāng)一個(gè)作為父內(nèi)存池的內(nèi)存池被銷毀時(shí),它的子內(nèi)存池也會(huì)被銷毀。所以,當(dāng)一個(gè)作為父內(nèi)存池的內(nèi)存池和它的子內(nèi)存池不再使用時(shí),不必將所有的內(nèi)存池一一銷毀,僅僅為父內(nèi)存池調(diào)用銷毀接口即可。
如果在創(chuàng)建內(nèi)存池時(shí)不指定父內(nèi)存池,那么一個(gè)全局的內(nèi)存池就是它的父內(nèi)存池。這個(gè)全局的內(nèi)存池是在第一次調(diào)用elr_mpl_init(初始化內(nèi)存池函數(shù))時(shí)被創(chuàng)建的,所有的內(nèi)存池結(jié)構(gòu)所占據(jù)的內(nèi)存空間都來自于這個(gè)全局內(nèi)存池。在最后一次調(diào)用elr_mpl_finalize(終止化函數(shù))內(nèi)存池時(shí),這個(gè)全局內(nèi)存池被銷毀。同時(shí),可以看出,所有的內(nèi)存池實(shí)例都是這個(gè)全局內(nèi)存池的直接或者間接的子內(nèi)存池,那么當(dāng)elr_mpl_finalize被調(diào)用后,所有的內(nèi)存池實(shí)例也將被銷毀,從而將內(nèi)存泄露的可能性降到了最低。
Emake子系統(tǒng)的內(nèi)存池也支持多線程,如果需要在多線程環(huán)境下使用它,則需要實(shí)現(xiàn)六個(gè)接口,并且在編譯時(shí)定義易語言常量ELR_USE_THREAD。
圖4示出了根據(jù)本發(fā)明的一個(gè)實(shí)施例的線程池工作模型的示意圖。
在Emake子系統(tǒng)中的依賴文件處理、嵌套遍歷處理、日志處理等邏輯較為復(fù)雜的過程中,各個(gè)接口可能會(huì)交叉使用和修改資源數(shù)據(jù),這樣就很容易導(dǎo)致并發(fā)問題,如果對(duì)于每個(gè)資源都要考慮如何保證其并發(fā)安全問題,那么整個(gè)分析過程就會(huì)變得很復(fù)雜,而復(fù)雜的邏輯往往容易有所疏漏。
如圖4所示的線程池模型就是用來屏蔽單次編譯的并發(fā)問題的,即編譯線程訪問自己的資源時(shí)不需要考慮其并發(fā)安全問題(多個(gè)編譯訪問的資源依然需要處理),具體地,可以將編譯的請(qǐng)求排序并調(diào)用線程池中的線程依次處理。
線程池模型包括如下幾個(gè)部分:
1、線程池管理器(ThreadPool),用于啟動(dòng)、增加、停用、管理線程池。
2、工作線程(WorkThread),為線程池中的線程,可將執(zhí)行結(jié)果放置到結(jié)果隊(duì)列。
3、請(qǐng)求接口(WorkRequest),在圖中未示出,用于創(chuàng)建請(qǐng)求對(duì)象,以供工作線程調(diào)度任務(wù)的執(zhí)行。
4、請(qǐng)求隊(duì)列(RequestQueue),用于存放和提取請(qǐng)求,線程池管理器向請(qǐng)求隊(duì)列中添加請(qǐng)求。
5、結(jié)果隊(duì)列(ResultQueue),用于存儲(chǔ)請(qǐng)求執(zhí)行結(jié)果,線程池管理器可以從結(jié)果隊(duì)列中獲取執(zhí)行結(jié)果。
線程池管理器通過添加請(qǐng)求(putRequest)的方法向請(qǐng)求隊(duì)列添加請(qǐng)求,這些請(qǐng)求事先需要通過傳遞工作函數(shù)、參數(shù)、結(jié)果處理函數(shù)、以及異常處理函數(shù)等實(shí)現(xiàn)請(qǐng)求接口,接著,初始化一定數(shù)量的工作線程,這些工作線程通過輪詢的方式不斷查看請(qǐng)求隊(duì)列,只要有請(qǐng)求存在,則會(huì)提取出請(qǐng)求并執(zhí)行。
然后,線程池管理器調(diào)用方法(poll)查看結(jié)果隊(duì)列是否有值,如果有值,則取出,調(diào)用結(jié)果處理函數(shù)執(zhí)行。
通過上述技術(shù)方案可知,Emake子系統(tǒng)的核心資源在于請(qǐng)求隊(duì)列和結(jié)果隊(duì)列,工作線程通過輪詢請(qǐng)求隊(duì)列獲得任務(wù),主線程通過查看結(jié)果隊(duì)列獲得執(zhí)行結(jié)果。
因此,隊(duì)列設(shè)計(jì)需要實(shí)現(xiàn)線程同步、一定阻塞和超時(shí)機(jī)制,以防止因不斷輪詢而導(dǎo)致的過多CPU(中央處理器)開銷。
另外,Emake子系統(tǒng)在開始工作之前,需要知道當(dāng)前的系統(tǒng)環(huán)境,比如標(biāo)準(zhǔn)庫(kù)在哪里、編譯器的安裝位置在哪里、需要安裝哪些組件等,通過指定編譯配置信息,Emake子系統(tǒng)就可以靈活適應(yīng)環(huán)境,編譯出各種環(huán)境都能運(yùn)行的機(jī)器碼等編譯配置信息。這些編譯配置信息保存在一個(gè)叫做project.ini的配置文件之中,它由ESB生成,Emake子系統(tǒng)通過讀取這個(gè)配置文件,獲知編譯配置信息。
另外,project.ini配置文件可以考慮到不同系統(tǒng)的差異,并且對(duì)各種編譯配置信息給出了默認(rèn)值,如果用戶的編譯環(huán)境比較特別,或者有一些特定的需求,也可以手動(dòng)向project.ini提供參數(shù)。
進(jìn)一步地,需要確定標(biāo)準(zhǔn)庫(kù)和頭文件的位置。
源碼用到的標(biāo)準(zhǔn)庫(kù)函數(shù)(standard library)和頭文件(header)可以存放在系統(tǒng)的任意目錄中,Emake子系統(tǒng)從配置文件中可以知道標(biāo)準(zhǔn)庫(kù)和頭文件的位置。一般來說,配置文件會(huì)給出一個(gè)清單,列出幾個(gè)具體的目錄,等到編譯時(shí),編譯器就按順序到這幾個(gè)目錄中,尋找目標(biāo)。
更進(jìn)一步地,需要確定源文件的依賴文件,換句話說,需要獲取到源碼文件之間的依賴關(guān)系,由源碼文件之間的依賴關(guān)系,編譯器可以確定編譯的先后順序。假定A文件依賴于B文件,Emake子系統(tǒng)應(yīng)該保證做到下面兩點(diǎn):
(1)只有在B文件編譯完成后,才開始編譯A文件。
(2)當(dāng)B文件發(fā)生變化時(shí),A文件會(huì)被重新編譯。
依賴關(guān)系保存在一個(gè)叫做.d的文件中,里面列出源文件的依賴文件。在確定依賴關(guān)系的同時(shí),Emake子系統(tǒng)也確定了,編譯時(shí)會(huì)用到哪些頭文件。
接下來,需要進(jìn)行頭文件的預(yù)編譯。
具體來說,不同的源碼文件可能引用同一個(gè)頭文件(比如stdio.h),編譯的時(shí)候,頭文件也必須一起編譯。因此,為了節(jié)省時(shí)間,Emake子系統(tǒng)會(huì)在編譯源碼之前,先編譯頭文件,這保證了頭文件只需編譯一次。
不過,并不是頭文件的所有內(nèi)容都會(huì)被預(yù)編譯,用來聲明宏的#define命令,就不會(huì)被預(yù)編譯。
預(yù)編譯完成后,編譯器就開始替換掉源碼中bash的頭文件和宏。
插入源碼是預(yù)編譯后的結(jié)果,編譯器在這一步還會(huì)移除注釋。
這一步稱為預(yù)處理,在完成預(yù)處理之后,Emake子系統(tǒng)就開始生成機(jī)器碼,對(duì)于有些編譯器來說,還存在一個(gè)中間步驟,即先把源碼轉(zhuǎn)為匯編碼,然后再把匯編碼轉(zhuǎn)為機(jī)器碼。
轉(zhuǎn)碼后的文件稱為object file(對(duì)象文件),對(duì)象文件還不能運(yùn)行,必須進(jìn)一步轉(zhuǎn)成可執(zhí)行文件。程序要正常運(yùn)行,還必須有stdout和fwrite這兩個(gè)函數(shù)的代碼,它們是由C語言的標(biāo)準(zhǔn)庫(kù)提供的。
Emake子系統(tǒng)的下一步工作,就是把外部函數(shù)的代碼(通常是后綴名為.lib和.a的文件)添加到可執(zhí)行文件中,即linking(連接)步驟,這種通過拷貝將外部函數(shù)庫(kù)添加到可執(zhí)行文件的方式,叫做static linking(靜態(tài)連接)。
以上結(jié)合附圖詳細(xì)說明了本發(fā)明的技術(shù)方案,通過本發(fā)明的技術(shù)方案,在源文件發(fā)生改變時(shí),需要通過正則匹配遍歷該源文件對(duì)應(yīng)的依賴文件,從而確定是否需要基于源碼狀態(tài)自動(dòng)執(zhí)行文件重新編譯,這樣,當(dāng)確定需要重新編譯時(shí),就能為從源文件起的所有文件實(shí)現(xiàn)自動(dòng)重新編譯,而無需大量人工操作,提升了軟件集成效率,降低了編譯成本。
以上所述僅為本發(fā)明的優(yōu)選實(shí)施例而已,并不用于限制本發(fā)明,對(duì)于本領(lǐng)域的技術(shù)人員來說,本發(fā)明可以有各種更改和變化。凡在本發(fā)明的精神和原則之內(nèi),所作的任何修改、等同替換、改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。
取決于語境,如在此所使用的詞語“如果”可以被解釋成為“在……時(shí)”或“當(dāng)……時(shí)”或“響應(yīng)于確定”或“響應(yīng)于檢測(cè)”。類似地,取決于語境,短語“如果確定”或“如果檢測(cè)(陳述的條件或事件)”可以被解釋成為“當(dāng)確定時(shí)”或“響應(yīng)于確定”或“當(dāng)檢測(cè)(陳述的條件或事件)時(shí)”或“響應(yīng)于檢測(cè)(陳述的條件或事件)”。
在本發(fā)明所提供的幾個(gè)實(shí)施例中,應(yīng)該理解到,所揭露的系統(tǒng)、裝置和方法,可以通過其它的方式實(shí)現(xiàn)。例如,以上所描述的裝置實(shí)施例僅僅是示意性的,例如,所述單元的劃分,僅僅為一種邏輯功能劃分,實(shí)際實(shí)現(xiàn)時(shí)可以有另外的劃分方式,例如,多個(gè)單元或組件可以結(jié)合或者可以集成到另一個(gè)系統(tǒng),或一些特征可以忽略,或不執(zhí)行。另一點(diǎn),所顯示或討論的相互之間的耦合或直接耦合或通信連接可以是通過一些接口,裝置或單元的間接耦合或通信連接,可以是電性,機(jī)械或其它的形式。
另外,在本發(fā)明各個(gè)實(shí)施例中的各功能單元可以集成在一個(gè)處理單元中,也可以是各個(gè)單元單獨(dú)物理存在,也可以兩個(gè)或兩個(gè)以上單元集成在一個(gè)單元中。上述集成的單元既可以采用硬件的形式實(shí)現(xiàn),也可以采用硬件加軟件功能單元的形式實(shí)現(xiàn)。
上述以軟件功能單元的形式實(shí)現(xiàn)的集成的單元,可以存儲(chǔ)在一個(gè)計(jì)算機(jī)可讀取存儲(chǔ)介質(zhì)中。上述軟件功能單元存儲(chǔ)在一個(gè)存儲(chǔ)介質(zhì)中,包括若干指令用以使得一臺(tái)計(jì)算機(jī)裝置(可以是個(gè)人計(jì)算機(jī),服務(wù)器,或者網(wǎng)絡(luò)裝置等)或處理器(Processor)執(zhí)行本發(fā)明各個(gè)實(shí)施例所述方法的部分步驟。而前述的存儲(chǔ)介質(zhì)包括:U盤、移動(dòng)硬盤、只讀存儲(chǔ)器(Read-Only Memory,ROM)、隨機(jī)存取存儲(chǔ)器(Random Access Memory,RAM)、磁碟或者光盤等各種可以存儲(chǔ)程序代碼的介質(zhì)。
以上所述僅為本發(fā)明的較佳實(shí)施例而已,并不用以限制本發(fā)明,凡在本發(fā)明的精神和原則之內(nèi),所做的任何修改、等同替換、改進(jìn)等,均應(yīng)包含在本發(fā)明保護(hù)的范圍之內(nèi)。