RT-Thread Kernel Study Notes-Understanding defunct zombie threads

RT-Thread Kernel Study Notes-Kernel Object rt_object

RT-Thread Kernel Study Notes-Kernel Object Management

RT-Thread Kernel Study Notes-Kernel Object Operation API

RT-Thread kernel study notes-kernel object initialization linked list organization

RT-Thread kernel study notes-in-depth understanding of the structure of the kernel object linked list

RT-Thread kernel study notes-understanding of the device model rt_device

RT-Thread Kernel Study Notes-Understanding defunct zombie threads

 

Preface

  • At present, everyone occasionally discusses the issue of RT-Thread thread exit, such as main thread, how to deal with it after return? Whether resources such as RAM have been released.
  • Recently, I was looking at the thread-related kernel source code, based on the kernel object rt_object management method, to sort out the processing flow after the thread exits.
  • rt_thread_defunct, the linked list structure of zombie threads, why is it called [zombie], the dictionary I checked. Function to reclaim the memory (heap) resources of the deleted thread.

 

Thread initialization and creation

  • rt_thread_init: statically initialize a thread. The thread structure and thread stack are global variables. After rt_thread_detach, the kernel object of this thread is removed from the kernel container linked list, [but] the thread structure and thread stack cannot be released because they are static and global. If you want to initialize and use this thread next time, you can still use the existing thread structure and thread stack after detachment for initialization. The characteristics of static threads: After initialization, the memory usage will not change.
  • rt_thread_create: Create a thread dynamically. Need to enable: RT_USING_HEAP, heap management. The created thread [Structure] and [Thread Stack] are dynamically applied for. When deleting this thread, you need to call rt_thread_delete. After deletion, the memory (heap) space occupied by the thread’s [structure] and [thread stack] can be released. After deleting, this thread no longer exists. If you want to start using it again, you need to recreate it. The characteristics of dynamic threads: After deletion, memory resources can be released.

 

Thread resource recovery

  • RT-Thread only reclaims thread memory resources of rt_thread_create.
  • When a thread is statically initialized or dynamically created, it will register: rt_thread_exit. After the thread exits, it will call rt_thread_exit.
  • In rt_thread_exit, the first step: remove the thread from the scheduling list. Step 2: A static thread will call: rt_object_detach to remove the thread kernel object from the kernel object container; a dynamic thread will add the thread structure pointer (operation handle) to the rt_thread_defunct zombie thread list instead of releasing it immediately The memory occupied by the thread. The operation of the zombie thread is executed in the idle thread. Step 3: Perform thread scheduling and switch threads. In the execution of the idle thread, it should be ensured that after the thread is deleted, the switching thread is scheduled immediately, and the resource recovery of the thread does not need to be too high priority.
  • In the idle thread: rt_thread_idle_excute is responsible for checking whether the rt_thread_defunct zombie thread list is empty, and if it is not empty, the memory release operation is executed. Remove from the thread list, release the thread stack, and release the kernel structure. Note that only dynamically created threads perform this operation.
/* 来自: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 thread exits

  • The above sorted out the exit of threads, the processing flow of zombie threads, and the exit of main thread. Basically, the flow can also be sorted out.
  • Static main thread, not enabled: RT_USING_HEAP, memory resources will not be released after exiting.
  • The dynamic main thread is enabled: After RT_USING_HEAP, the memory resources are released after exiting.
  • Actually comparing the release size of memory resources, it is found that dynamic application will take up a little extra memory resources, such as 12 bytes. This part will be further sorted out after memory management.

 

Resource recovery of dynamic threads:

When RT_USING_HEAP
main exists: the thread stack size is 2048

msh >free
total memory: 89568
used memory : 10656
maximum allocated memory: 10656

When main does not exist:

msh >free
total memory: 89568
used memory : 8456
maximum allocated memory: 10656

Main thread stack, resource after return: 2200 Bytesspace

2048 栈空间 + 12Byte(rt_malloc管理占用)
128Byte rt_thread结构体大小,sizeof(struct rt_thread) + 12Byte(rt_malloc管理占用,内核对象)。

合计:2048+12+128+12 = 2200。

 

to sum up

  • Familiar with the initialization, creation, detachment (de-initialization), deletion and other operations of RT-Thread threads.
  • Familiar with dynamically created threads, after deleting, join the zombie thread list, memory resource recovery process.
  • Understand the exit process of ordinary threads such as main thread.
  • Continue to study the following knowledge points with questions:

    • Where is the work flow of the scheduler performed? How does it work?
    • Thread timer, each thread will create one, after the thread is deleted, the recycling process of timer resources.
    rt_thread_delete /* 删除线程,如何处理定时器 */
    
    rt_timer_detach(&(thread->thread_timer)); /* 定时器资源的回收流程 */
    • When creating a thread, I changed the thread name (name) to RT_NULL, it can still run normally, but does this have any effect?
    • In the rt_thread structure: the linked list of kernel objects is used to join the kernel object container, and the member: the workflow of tlist.
    • Consideration of historical issues: rt_thread structure:
    /**
    * 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 */

Can it be changed to:

/**
 * Thread structure
 */
struct rt_thread
{
    struct rt_object parent;                            /**< inherit from rt_object */

Guess you like

Origin blog.csdn.net/tcjy1000/article/details/114221137