The idle thread is a special thread in the system thread that has the lowest priority, and when no other threads in the system can run, the scheduler dispatches to the idle thread. Idle threads are usually a dead loop and are never suspended. The Rt-thread real-time operating system provides a hook function for idle threads (a hook function: a user-supplied piece of code that sets a hook on a path running on the system, and when the system passes this position, executes the hook function and then returns to its normal path), It allows the system to perform certain operations during idle time, such as flashing the system lights, power management, and so on. In addition to calling the hook function, Rt-thread also puts the thread cleanup (rt_thread->cleanup callback function) function, the real thread deletion action into the idle line approached (when the thread is detached or removed, only the state of the thread is changed to a closed state and no longer participates in system scheduling ).
Idle thread Function Interface: (defined in src/idle.c)
Idle thread Initialization:/** * @ingroup systeminit * * This function would initialize idle thread, then start it. * @note This function must be Invoked when system init. */voidRt_thread_idle_init (void){ /*Initialize Thread*/Rt_thread_init (&Idle,"Tidle", Rt_thread_idle_entry,//Idle thread entry functionRt_null,//entry function parameter is empty&rt_thread_stack[0],//idle thread stack address sizeof(Rt_thread_stack),//stack size, default is 128 bytes, if using the hook function or dynamic heap is 256 bytes, in IDLE.C macro definitionRt_thread_priority_max-1,//idle thread has the lowest priority +);//time slice for 32 clock beats /*Startup*/Rt_thread_startup (&idle);}
Idle thread entry function: Static void rt_thread_idle_entry (void *parameter) { while (1) { #ifdef Rt_using_hook if (Rt_thread_idle_hook! = rt_null) rt_thread_idle_hook (); // If a hook is used and the hook function is not empty, the hook function is executed #endif Rt_thread_idle_excute (); // the real execution function of the idle thread }}
Idle thread execution function:voidRt_thread_idle_excute (void){ /*Loop until there is no dead thread. So one call to Rt_thread_idle_excute * would do all the cleanups. */ while(_has_defunct_thread ())//Check for zombie threads in the list of zombie threads, using if (!rt_list_isempty (&RT_THREAD_DEFUNCT)) in previous versions so that only one zombie thread can be purged at a time{rt_base_tLock; rt_thread_t thread; #ifdef rt_using_module rt_module_t MODULE=Rt_null;#endifRt_debug_not_in_interrupt; //ensure that this function is not in interrupt service, if Rt_debug_context_check is 1 in rtdebug.h, the macro indicates that the function cannot be used to interrupt the ISR. Check if the Rt_interrupt_nest interrupt nesting counter is zero /*Disable Interrupt*/ Lock=rt_hw_interrupt_disable (); /*re-check Whether list is empty*/ if(_has_defunct_thread ())//again determine if rt_thread_defunct is empty, if not empty { /*get defunct thread*/Thread=rt_list_entry (Rt_thread_defunct.next,structRt_thread, tlist); //get Zombie threads to be recycled#ifdef Rt_using_module/*get thread ' s parent module*/Module= (rt_module_t) thread->module_id;//Get module ID /*if the thread is module ' s main thread*/ if(Module! = Rt_null && Module->module_thread = =thread) { /*Detach module ' s main thread*/Module->module_thread = Rt_null;//Emptying Module Threads }#endif /*Remove defunct thread*/Rt_list_remove (& (Thread->tlist));//Reset Line Threads node is the initial value, that is, the node next and Prev both point to their own node, the thread from the list of zombie threads removed /*Invoke thread Cleanup*/ if(Thread->cleanup! =rt_null) Thread->cleanup (thread);//perform a thread cleanup function /*if it ' s a system object, not delete it*/ if(Rt_object_is_systemobject (rt_object_t) thread) = = Rt_true)//if the zombie thread kernel object is a static object, the kernel object is not deleted { /*Enable interrupt*/rt_hw_interrupt_enable (Lock); return; } } Else //If you judge again rt_thread_defunct Zombie line threads is empty { /*Enable interrupt*/rt_hw_interrupt_enable (Lock); /*May the defunct thread list was removed by others, just return*/ return; } /*Enable interrupt*/rt_hw_interrupt_enable (Lock); #ifdef rt_using_heap//The program runs to this, stating that the previously processed zombie thread is a dynamically created thread#ifDefined (rt_using_module) && defined (Rt_using_slab)/*The thread belongs to an application module*/ if(Thread->flags &rt_object_flag_module) Rt_module_free ((rt_module_t) thread->module_id, THREAD->STACK_ADDR);//Release module Main Line stacks occupied memory Else#endif /*release thread ' s stack*/Rt_kernel_free (thread->STACK_ADDR);//releasing the memory of the dynamic line stacks /*Delete Thread Object*/Rt_object_delete ((rt_object_t) thread);//Remove the dynamic thread kernel object, which is removed from the list of kernel objects of the current type, while freeing up the space occupied by the kernel objects (if the module function is used, the space occupied by the module ID is freed)#endif#ifdef Rt_using_moduleif(Module! =rt_null) { externrt_err_t Rt_module_destroy (rt_module_t module); /*if sub thread list and main thread is all empty*/ //if the main thread of the module is empty, and the child thread object list is empty if((Module->module_thread = = rt_null) &&Rt_list_isempty (&module->module_object[rt_object_class_thread].object_list)) {Module->nref--; } /*Destroy Module*/ if(Module->nref = =0) Rt_module_destroy (module);//Destroy Module }#endif }}
The above code shows that a large part of the idle thread's job is to reclaim the zombie thread. So how do these threads come about?
When a thread is detached or deleted, it is added to the Recycle chain list rt_thread_defunct, which is defined in the SCHEDULER.C source file and is specifically used to hold the thread to be recycled.
Rt-thread idle thread of the kernel