您好,登錄后才能下訂單哦!
這篇文章主要介紹“什么是defunct僵尸線程”,在日常操作中,相信很多人在什么是defunct僵尸線程問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”什么是defunct僵尸線程”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
目前大家偶爾會討論RT-Thread線程退出的問題,如main線程,return后,怎么處理的?RAM等資源,是否得到釋放。
最近在看線程相關的內核源碼,基于內核對象rt_object管理方法,梳理一下線程退出后的處理流程。
rt_thread_defunct,僵尸線程的鏈表結構,為什么叫【僵尸】,我查的字典。作用,回收刪除的線程的內存(堆)資源。
rt_thread_init:靜態初始化一個線程,線程結構體、線程棧,都是全局的變量。rt_thread_detach后,這個線程的內核對象從內核容器鏈表里移除,【但】線程結構體、線程棧,因為是靜態全局的,無法釋放。若下次再想初始化并使用這個線程,依舊可以使用這個detach后的現有的線程結構體、線程棧進行初始化。靜態線程的特點:初始化后,內存的占用,就不會改變。
rt_thread_create:動態創建一個線程。需要使能:RT_USING_HEAP,堆管理。創建的線程【結構體】與【線程棧】都是動態申請出來的。刪除這個線程時,需要調用rt_thread_delete。刪除后,線程的【結構式】與【線程棧】占用的內存(堆)空間,可以釋放。刪除后,這個線程不存在了,想再次開啟使用,需要重新創建。動態線程的特點:刪除后,內存資源可以釋放。
RT-Thread 只回收rt_thread_create的線程內存資源。
靜態初始化或動態創建線程時,會注冊:rt_thread_exit,線程退出后,會調用rt_thread_exit。
rt_thread_exit中,第一步:把線程從調度鏈表移除。第二步:靜態的線程,會調用:rt_object_detach,從內核對象容器里移除線程內核對象;動態線程,會把線程的結構體指針(操作句柄),加入rt_thread_defunct僵尸線程鏈表中,而不是立即釋放線程占用的內存。僵尸線程的操作,是在idle線程中執行。第三步:執行線程調度,切換線程。在idle線程執行,應該是保證這個線程刪除后,立即調度切換線程,線程的資源回收不需要太高的優先級。
idle 線程中: rt_thread_idle_excute 負責查看rt_thread_defunct僵尸線程鏈表是否為空,如果不為空,則執行內存釋放的操作。從線程鏈表移除、釋放線程棧、釋放內核結構體。注意,只有動態創建的線程,執行此操作。
/* 來自:rt_thread_idle_excute 片段 */ /* remove defunct thread */ rt_list_remove(&(thread->tlist)); /* release thread's stack */ RT_KERNEL_FREE(thread->stack_addr); /* delete thread object */ rt_object_delete((rt_object_t)thread);
上面梳理了線程的退出,僵尸線程的處理流程,main線程的退出,基本上也可以梳理流程了
靜態的main線程,未使能:RT_USING_HEAP,退出后,內存資源不會釋放。
動態的main線程,使能了:RT_USING_HEAP后,退出后,內存資源得到釋放。
實際對比內存資源的釋放大小,發現,動態申請,會額外占用一點內存資源,如12字節,這部分在后面內存管理后再深入的梳理。
RT_USING_HEAP main存在時:線程棧大小為2048
msh >free total memory: 89568 used memory : 10656 maximum allocated memory: 10656
main不存在時:
msh >free total memory: 89568 used memory : 8456 maximum allocated memory: 10656
main的線程棧,return后的資源:2200 Bytes
空間
2048 棧空間 + 12Byte(rt_malloc管理占用) 128Byte rt_thread結構體大小,sizeof(struct rt_thread) + 12Byte(rt_malloc管理占用,內核對象)。 合計:2048+12+128+12 = 2200。
熟悉RT-Thread線程的初始化、創建、脫離(反初始化)、刪除等操作。
熟悉動態創建的線程,刪除后,加入僵尸線程鏈表,內存資源回收流程。
理解普通線程如main線程的退出流程。
帶著問題后續繼續研究以下知識點:
調度器的工作流程,在哪里執行?如何運作?
線程定時器,每個線程都會創建一個,線程刪除后,定時器資源的回收流程。
rt_thread_delete /* 線程的定時器,使用detach方式,定時器資源回收流程 */ rt_timer_detach(&(thread->thread_timer)); /* 定時器資源的回收流程 */
創建線程時,我把線程的名字(name)改為RT_NULL,依舊可以正常的運行,但這樣是否有影響?
rt_thread 結構體中:內核對象的鏈表用于加入內核對象容器,成員:tlist的工作流程。
歷史問題:rt_thread結構體:
/** * Thread structure */ struct rt_thread { /* rt object */ char name[RT_NAME_MAX]; /**< the name of thread */ rt_uint8_t type; /**< type of object */ rt_uint8_t flags; /**< thread's flags */ #ifdef RT_USING_MODULE void *module_id; /**< id of application module */ #endif rt_list_t list; /**< the object list */
是否可以改為如下:
/** * Thread structure */ struct rt_thread { struct rt_object parent; /**< inherit from rt_object */
到此,關于“什么是defunct僵尸線程”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。