專利名稱:線程托管函數(shù)的方法
技術(shù)領(lǐng)域:
本發(fā)明涉及一種托管函數(shù)的方法,尤其涉及一種線程托管函數(shù)的方法。
背景技術(shù):
在利用線程進(jìn)行編程時(shí),可能希望得到線程退出的通知,在線程即將結(jié)束退出的 時(shí)刻做些資源清理的工作,或者當(dāng)線程結(jié)束時(shí)需要設(shè)置一些標(biāo)志、發(fā)送消息通知等等。如果是一個(gè)結(jié)構(gòu)簡(jiǎn)單的程序,可以確切地知道線程的出口,那么可以將清理工作 放在線程出口點(diǎn),但如果是一個(gè)復(fù)雜的線程,存在多個(gè)出口點(diǎn),則維護(hù)起來(lái)比較麻煩?;蛘?某個(gè)子函數(shù),它可能被多個(gè)線程調(diào)用,又想在線程結(jié)束時(shí)做些處理(如資源清理),就不容 易預(yù)測(cè)線程出口點(diǎn)的位置。
發(fā)明內(nèi)容
鑒于以上內(nèi)容,有必要提供一種線程托管函數(shù)的方法,可以在線程結(jié)束這一特殊 時(shí)刻被調(diào)用,減少程序的復(fù)雜度和耦合度,使程序中各個(gè)模塊之間的關(guān)系簡(jiǎn)單和清晰。一種線程托管函數(shù)的方法,該方法包括如下步驟步驟1,在主函數(shù)中創(chuàng)建一個(gè)線程;步驟2,執(zhí)行線程的入口函數(shù),在線程的入口函數(shù)中調(diào)用線程函數(shù);步驟3,在線程函數(shù)中注冊(cè)線程托管函數(shù) ’及步驟4,當(dāng)線程函數(shù)執(zhí)行完畢時(shí),調(diào)用上述注冊(cè)的線程托管函數(shù),執(zhí)行結(jié)束。相較于現(xiàn)有技術(shù),程序員可以借助設(shè)置一個(gè)或若干個(gè)線程托管函數(shù),這些函數(shù)會(huì) 在線程結(jié)束即將退出的時(shí)刻被調(diào)用,當(dāng)線程執(zhí)行到線程托管函數(shù)的代碼時(shí),會(huì)在當(dāng)前線程 上設(shè)置相應(yīng)的記錄,當(dāng)線程退出用戶代碼,進(jìn)入準(zhǔn)備結(jié)束狀態(tài)時(shí),會(huì)自動(dòng)調(diào)用先前托管的函 數(shù)。如此一來(lái),某個(gè)子模塊的程序員也不必關(guān)心自己的模塊會(huì)被哪個(gè)線程調(diào)用、調(diào)用線程的 出口點(diǎn)在哪里,只要設(shè)置托管函數(shù)即可在線程結(jié)束的時(shí)刻得以執(zhí)行預(yù)期的操作。線程托管 函數(shù)減少程序的復(fù)雜度和耦合度,使代碼和各個(gè)模塊之間的關(guān)系更簡(jiǎn)單和清晰。
圖1是本發(fā)明線程托管函數(shù)的方法較佳實(shí)施例的主流程圖。圖2是圖1中步驟S30的細(xì)化流程圖。圖3是圖1中步驟S40的細(xì)化流程圖。
具體實(shí)施例方式如圖1所示,是本發(fā)明線程托管函數(shù)的方法較佳實(shí)施例的流程圖。在本較佳實(shí)施 例中,首先以如下構(gòu)建的代碼來(lái)進(jìn)行說(shuō)明用戶定義的線程托管函數(shù)代碼Void OnQuit(PVoid pUserData)//
3
{Assert ((Int32) pUserData = = 0x1234) ;// 預(yù)期 pUserData = = 0x1234,否則 中 assertCThread: Sleep (1000, NULL) ;// 使線程睡眠 1 秒鐘CConsole: :WriteLine( "In OnQuit function. ”);// 打印到屏幕輸出}用戶定義的線程函數(shù)代碼ECode UserRoutine (…){CConsole: :WriteLine( "Entered UserRoutine. ”);// 打印到屏幕輸出CThread: AtQuit (&0nQuit, (PVoid) 0x1234) ;//向當(dāng)前線程注冊(cè)線程托管函數(shù)CConsole: :WriteLine( "Leaving UserRoutine. ”);// 打印到屏幕輸出ReturnNOERROR;//退出用戶代碼}主函數(shù)代碼ECode ElastosMain (…){IThread氺pThreadCConsole: :WriteLine( "Before CThread: :New (),,);//打印到屏幕輸出CThread::New(&UserRoutine,0, NULL, &pThread) ;// 創(chuàng)建一個(gè)線程 UserRoutinepThread- > Join (INFINITE, NULL) ;// 等待線程結(jié)束CConsole: :WriteLine( "After Join()”);//打印到屏幕輸出return N0ERR0R_EXIT ;//直接退出程序}用圖1所示的流程描述上述構(gòu)建的代碼。步驟S10:在主函數(shù)中創(chuàng)建一個(gè)線程。該線程運(yùn)行用于執(zhí)行用戶定義的線程 函數(shù)。具體而言,上述主函數(shù)的代碼中,首先聲明一個(gè)線程指針pThread,然后通過(guò)創(chuàng) 建動(dòng)作,艮p CThread: :New(&UserRoutine,0, NULL, &pThread)創(chuàng)建一個(gè)線程,該線程 名稱為 UserRoutine。代碼中的 CConsole: :WriteLine( "Before CThread: :New() ”) 及CConsole: :WriteLine( "After Join(),,)是通過(guò)打印的方式查看代碼是否執(zhí) 行。具體而言,若屏幕上顯示出‘‘After JoinO”,則表明主函數(shù)MainO的代碼中 CConsole: :WriteLine( "After JoinO”)之前的代碼已經(jīng)執(zhí)行完畢。步驟S20 執(zhí)行線程的入口函數(shù),在線程的入口函數(shù)中調(diào)用線程函數(shù)。入口函數(shù)的 具體代碼如下ECode ThreadEntry (PVoid pParam)//線程的入 口函數(shù){ECode ec =(氺pUserFunc) (pParam);CleanupListQ ;//清理線程托管函數(shù)鏈表
4
}。上述代碼中ECode ec = (*pUserFunc) (pParam)為調(diào)用用戶實(shí)現(xiàn)的線程函數(shù),其 中pParam為參數(shù),具體而言,在本較佳實(shí)施例中,所述調(diào)用的線程函數(shù)為UserRoutineO。步驟S30 在線程函數(shù)中注冊(cè)線程托管函數(shù)。上述用戶定義的線程函數(shù)的代碼中, 通過(guò)調(diào)用CThread::AtQuit即可向當(dāng)前線程注冊(cè)托管函數(shù),當(dāng)線程結(jié)束時(shí),會(huì)自動(dòng)調(diào)用被 托管的函數(shù)。步驟S40 當(dāng)線程函數(shù)執(zhí)行完畢時(shí),調(diào)用上述注冊(cè)的線程托管函數(shù),執(zhí)行結(jié)束。當(dāng)上述步驟執(zhí)行完畢時(shí),屏幕輸出如下Before CThread: :New()Entered UserRoutine...Leaving UserRoutine...In OnQuit function...After Join()上述線程托管函數(shù)主要目的在于當(dāng)線程UserRoutine執(zhí)行結(jié)束時(shí),使當(dāng)前線程睡 眠1秒鐘。從屏幕輸出可知,當(dāng)線程函數(shù)UserRoutineO返回時(shí),線程UserRoutine并沒(méi)有立 即結(jié)束,而是進(jìn)入托管函數(shù)OnQuit ()中,當(dāng)OnQuit結(jié)束后,主函數(shù)ElastosMain中的Join 才返回。在本較佳實(shí)施例中,但不限于,以編程語(yǔ)言C的函數(shù)注冊(cè)線程托管函數(shù),在其他實(shí) 施例中,用戶也可以將一個(gè)其他編程語(yǔ)言如C++的函數(shù)注冊(cè)線程托管函數(shù)。此外,用戶也可以為一個(gè)線程注冊(cè)多個(gè)線程托管函數(shù),這些線程托管函數(shù)會(huì)在線 程結(jié)束退出時(shí)按照注冊(cè)順序的相反順序被調(diào)用執(zhí)行。在本較佳實(shí)施例中,線程UserRoutine 注冊(cè)的線程托管函數(shù)為OnQuit (),當(dāng)線程UserRoutine執(zhí)行完畢時(shí),調(diào)用線程托管函數(shù) OnQuit ()。如圖2所示,是圖1中步驟S30中在線程函數(shù)中注冊(cè)線程托管函數(shù)的細(xì)化流程圖。 線程函數(shù)中注冊(cè)線程托管函數(shù)是將線程函數(shù)需要調(diào)用的線程托管函數(shù)的指針插入到線程 托管函數(shù)鏈表中。在本較佳實(shí)施例中,線程函數(shù)通過(guò)CThread: AtQuit注冊(cè)線程托管函數(shù), 即通過(guò)函數(shù)AtQuitO進(jìn)行注冊(cè)。所述函數(shù)AtQuit ()代碼如下ECode CThread:AtQuit([in]*/PThreadQuitRoutine pEntry,/氺[in]氺/PVoid pUserData)CList*pList ;{CThread: :GetTls0bject (TLS_AutoCallList,&pList) ;//從 TLS 上獲得線程托管 函數(shù)鏈表指針I(yè)f (pList == NULL) {pList = new CList ;//創(chuàng)建一個(gè)線程托管函數(shù)鏈表的類對(duì)象pListCThread: :SetTlsObject(TLS_AutoCallList, pList) ;// 將 pList 保存在 TLS 上}
pList- > Insert (pEntry,pUserData) ;//向線程托管函數(shù)鏈表插入一個(gè)線程托 管函數(shù)指針return N0ERR0R ;}用圖2所示的流程描述上述構(gòu)建的代碼。步驟S301,聲明一個(gè)線程托管函數(shù)鏈表的類指針。具體而言,代碼為 CList^pList。步驟S302,通過(guò)所述聲明的類指針創(chuàng)建一個(gè)線程托管函數(shù)鏈表的類對(duì)象。具體而 言,代石馬為 pList = new CList。步驟S303,將線程函數(shù)中的線程托管函數(shù)指針插入到線程托管函數(shù)鏈表的類對(duì)象 中,實(shí)現(xiàn)一個(gè)線程托管函數(shù)鏈表,即完成了在線程函數(shù)中注冊(cè)線程托管函數(shù)。具體而言,代 碼為pList- > Insert (pEntry,pUserData)。在本較佳實(shí)施例中,插入的線程托管函數(shù)指 針為線程UserRoutine注冊(cè)的托管函數(shù)OnQuit ()的指針。此外,由于線程函數(shù)在第一次注冊(cè)線程托管函數(shù)之后,線程托管函數(shù)鏈表已經(jīng)存 在,當(dāng)線程函數(shù)注冊(cè)多個(gè)線程托管函數(shù)時(shí),為保證每個(gè)線程中只有一個(gè)線程托管函數(shù)鏈表, 可以直接將線程托管函數(shù)指針插入到已經(jīng)存在的線程托管函數(shù)鏈表中。具體做法為判斷 線程托管函數(shù)鏈表是否為空,若不為空,直接將線程托管函數(shù)指針插入到線程托管函數(shù)鏈 表中。具體而言,代碼如下If (pList == NULL) {
}pList- > Insert(pEntry, pUserData)。如圖3所示,是圖1中步驟S40中調(diào)用注冊(cè)的線程托管函數(shù)的細(xì)化流程圖。每個(gè)線 程都保存一個(gè)線程托管函數(shù)鏈表,當(dāng)線程即將結(jié)束的時(shí)候會(huì)自動(dòng)檢查這個(gè)鏈表,如果不為 空則遍歷它,并釋放每個(gè)成員對(duì)象,從而實(shí)現(xiàn)線程托管函數(shù)的調(diào)用。在本較佳實(shí)施例中,線 程托管函數(shù)鏈表pList存放在該線程的一個(gè)Thread Local Storage (TLS 線程本地存儲(chǔ)) 槽中,在線程執(zhí)行的時(shí)候,可以直接在該線程的TLS槽獲取線程托管函數(shù)鏈表,在其它實(shí)施 例中,也可以將線程托管函數(shù)鏈表存放于其它儲(chǔ)存的區(qū)域。調(diào)用上述注冊(cè)的線程托管函數(shù) 的代碼如下ECode CleanupList (){CThread: :GetTls0bject (TLS_AutoCallList, &pList);If (pList == NULL) {Return N0ERR0R ;}PThreadQuitRoutine pEntry ;PVoid pUserData ;pHeader = pList ;pList = pList- > Prev();
While (pList ! = pHeader) {//遍歷線程托管函數(shù)鏈表,并調(diào)用線程托管函數(shù)pList- > GetCurrent(&pEntry, &pUserData) ;// 獲取線程托管函數(shù)鏈表當(dāng)前節(jié) 點(diǎn)的線程托管函數(shù)指針pEntry (pUserData) ;//通過(guò)線程托管函數(shù)指針調(diào)用線程托管函數(shù)pList = pList- > PrevO ;//繼續(xù)反向遍歷線程托管函數(shù)鏈表}Delete pList ;}用圖3所示的流程描述上述構(gòu)建的代碼。步驟S401,獲取線程托管函數(shù)鏈表,即在線程函數(shù)的TLS槽中獲取線程托管函數(shù) 鏈表。具體代碼為 CThread: :GetTlsObject (TLS_AutoCallList, &pList)。步驟S402,判斷線程托管函數(shù)鏈表是否為空。具體代碼為If (pList == NULL)。步驟S403,若線程托管函數(shù)鏈表不為空,則遍歷線程托管函數(shù)鏈表,獲取線程托管 函數(shù)鏈表中的線程托管函數(shù)指針,并通過(guò)獲取的線程托管函數(shù)指針調(diào)用該線程托管函數(shù)。 在本較佳實(shí)施例中,所調(diào)用的線程托管函數(shù)為OnQuitO,使線程UserRoutine睡眠1秒鐘。 遍歷的方式,但不限于,是反向遍歷線程托管函數(shù)鏈表,即按照倒序的方式依次讀取線程 托管函數(shù)鏈表中的數(shù)據(jù),在其它實(shí)施例中,用戶也可以通過(guò)正向遍歷線程托管函數(shù)鏈表。步驟S404,判斷線程托管函數(shù)鏈表是否遍歷完畢。步驟S405,若線程托管函數(shù)鏈表遍歷完畢,則刪除線程托管函數(shù)鏈表,之后流程結(jié) 束。具體代碼為Delete pList。在步驟S402中,若線程托管函數(shù)鏈表為空,則直接結(jié)束流程。具體代碼為If (pList == NULL){Return N0ERR0R ;// 直接退出}在步驟S404中,若線程托管函數(shù)鏈表沒(méi)有遍歷完畢,則轉(zhuǎn)到步驟S403。最后所應(yīng)說(shuō)明的是,以上實(shí)施例僅用以說(shuō)明本發(fā)明的技術(shù)方案而非限制,盡管參 照以上較佳實(shí)施例對(duì)本發(fā)明進(jìn)行了詳細(xì)說(shuō)明,本領(lǐng)域的普通技術(shù)人員應(yīng)當(dāng)理解,可以對(duì)本 發(fā)明的技術(shù)方案進(jìn)行修改或等同替換,而不脫離本發(fā)明技術(shù)方案的精神和范圍。
權(quán)利要求
一種線程托管函數(shù)的方法,其特征在于,該方法包括如下步驟步驟1,在主函數(shù)中創(chuàng)建一個(gè)線程;步驟2,執(zhí)行線程的入口函數(shù),在線程的入口函數(shù)中調(diào)用線程函數(shù);步驟3,在線程函數(shù)中注冊(cè)線程托管函數(shù);及步驟4,當(dāng)線程函數(shù)執(zhí)行完畢時(shí),調(diào)用上述注冊(cè)的線程托管函數(shù),執(zhí)行結(jié)束。
2.如權(quán)利要求1所述的線程托管函數(shù)的方法,其特征在于,所述步驟3包括如下步驟 聲明一個(gè)線程托管函數(shù)鏈表的類指針;通過(guò)所述聲明的類指針創(chuàng)建一個(gè)線程托管函數(shù)鏈表的類對(duì)象;及 將線程函數(shù)中的線程托管函數(shù)指針插入到線程托管函數(shù)鏈表的類對(duì)象中,實(shí)現(xiàn)一個(gè)線 程托管函數(shù)鏈表。
3.如權(quán)利要求2所述的線程托管函數(shù)的方法,其特征在于,所述線程托管函數(shù)鏈表包 括線程托管函數(shù)指針。
4.如權(quán)利要求2所述的線程托管函數(shù)的方法,其特征在于,所述線程托管函數(shù)鏈表存 放在該線程的線程本地存儲(chǔ)槽中。
5.如權(quán)利要求2所述的線程托管函數(shù)的方法,其特征在于,所述步驟4包括如下步驟 獲取線程托管函數(shù)鏈表;判斷線程托管函數(shù)是否為空;若線程托管函數(shù)鏈表不為空,遍歷線程托管函數(shù)鏈表,獲取線程托管函數(shù)鏈表中的線 程托管函數(shù)指針,并通過(guò)獲取的線程托管函數(shù)指針調(diào)用該線程托管函數(shù); 當(dāng)線程托管函數(shù)鏈表遍歷完畢,刪除線程托管函數(shù)鏈表;及 若該線程托管函數(shù)鏈表為空,則執(zhí)行結(jié)束。
6.如權(quán)利要求5所述的線程托管函數(shù)的方法,其特征在于,所述遍歷的方式為反向遍歷。
全文摘要
一種線程托管函數(shù)的方法,該方法包括如下步驟步驟1,在主函數(shù)中創(chuàng)建一個(gè)線程;步驟2,執(zhí)行線程的入口函數(shù),在線程的入口函數(shù)中調(diào)用線程函數(shù);步驟3,在線程函數(shù)中注冊(cè)線程托管函數(shù);步驟4,當(dāng)線程函數(shù)執(zhí)行完畢時(shí),調(diào)用上述注冊(cè)的線程托管函數(shù),執(zhí)行結(jié)束。利用本發(fā)明可以減少程序的復(fù)雜度和耦合度,使程序中各個(gè)模塊之間的關(guān)系簡(jiǎn)單和清晰。
文檔編號(hào)G06F9/48GK101866300SQ20091004914
公開(kāi)日2010年10月20日 申請(qǐng)日期2009年4月14日 優(yōu)先權(quán)日2009年4月14日
發(fā)明者宋世軍, 陳榕 申請(qǐng)人:上??铺┦兰o(jì)科技有限公司