Threadx 线程调度

Threadx os 线程调度方法:
1,基于优先级的调度,高优先级线程抢占低优先级线程
2,同一优先级线程可以采用基于时间片轮转调度方式
3,线程主动挂起,其他线程获得调度执行
几种方式同时采用,联合进行线程调度。
通过创建线程时设置时间片为0,可以禁止基于时间片轮转调度。

基于优先级抢占调度

通过中断或消息驱动进行调度。
1,高优先级线程抢占低优先级线程
2,只要有高优先级线程执行,低优先级线程无法执行
3,高优先级线程可以主动挂起,低优先级线程恢复执行
4,系统中所有线程优先级相同,需要执行线程主动挂起,下一就绪线程才有机会得到调度执行。
举例:
1,线程a执行,发送消息给线程b,线程b优先级高,保证实时性,线程b立即抢占线程a,获得处理器执行
2,线程b执行过程中,发生硬件中断,进行中断处理。中断处理中唤醒了线程c。
3,中断处理完成返回时,由于线程c优先级最高,切换到线程c执行。
4,线程c处理完,主动挂起,由于之前线程b被抢占,并且是系统中优先级最高线程,线程b获取执行权限。
5,线程b给线程a发送消息,这是线程a并没有立即执行。因为线程a优先级低于线程b。
6,线程b处理完,主动挂起。线程a成为系统中优先级最高线程,切换到线程a执行。

在这里插入图片描述## 基于时间片轮转调度方式
针对相同优先级线程进行调度,需要时钟中断进行驱动。一般设置周期性定时器,中断处理时,计算执行线程时间片是否用尽,如果时间片用尽,切换到下一个线程执行。相当于相同优先级几个线程平均分配处理器资源。

在这里插入图片描述

VOID   _tx_timer_interrupt(VOID)
{
    _tx_timer_system_clock++;                                           /*  系统滴答时间加              */
    if (_tx_timer_time_slice) {                                         /*  如果有剩余的时间片          */
		_tx_timer_time_slice--;                                         /*  时间片调整、减一            */
		if (_tx_timer_time_slice == 0) {                                /*  如果当前时间片耗尽          */
			_tx_timer_expired_time_slice =  TX_TRUE;                    /*  设置标识                    */
		}
    }

    if (*_tx_timer_current_ptr) {                                       /*  是否有定时器需要处理        */
        _tx_timer_expired =  TX_TRUE;
    } else {
        _tx_timer_current_ptr++;                                        /*  指向下一时刻定时器就绪链表头*/
        if (_tx_timer_current_ptr == _tx_timer_list_end){
            _tx_timer_current_ptr =  _tx_timer_list_start;
		}
    }

    if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) {        /*  有事情要做                  */
		if (_tx_timer_expired) {
		    _tx_timer_expired   = TX_FALSE;
			_tx_thread_preempt_disable++;
	
			_tx_thread_resume(&_tx_timer_thread);                       /*  回复定时器线程              */
		}
		/* 时间片用尽 */
		if (_tx_timer_expired_time_slice) {
    		_tx_timer_expired_time_slice    = TX_FALSE;
			if (_tx_thread_time_slice() == TX_FALSE) {                  /*  不需要切换,载入分配的时间片*/
				_tx_timer_time_slice =  _tx_thread_current_ptr -> tx_time_slice;
			}
		 } 
    }
}

执行线程时间片用尽,调用_tx_thread_time_slice判断是否进行线程切换。

UINT    _tx_thread_time_slice(VOID)
{

TX_INTERRUPT_SAVE_AREA
REG_1 UINT          status;             /* Time-slice status flag	    */
REG_2 TX_THREAD     *thread_ptr;        /* Thread priority head pointer */


    /* Pickup the current thread pointer.  */
    thread_ptr =  _tx_thread_current_ptr;

    /* Default time-slice status to false.  A true value indicates this
       routine did indeed perform a time-slice.  */
    status =  TX_FALSE;

    /* Lockout interrupts while thread attempts to relinquish control.  */
    TX_DISABLE

    /* Make sure the thread is still active, i.e. not suspended.  */
    if (thread_ptr -> tx_state == TX_READY)
    {

        /* Setup a fresh time-slice for the thread.  */
        thread_ptr -> tx_time_slice =  thread_ptr -> tx_new_time_slice;

        /* Check to make sure preemption is enabled.  */
        if (_tx_thread_preempt_disable)
        {

            /* Preemption is disabled by the system, set time-slice to 1 for retry.  */
            thread_ptr -> tx_time_slice =  1;

            /* Set status to false.  */
            status =  TX_FALSE;
        }

        /* Determine if there is another thread at the same priority.  */
        #def 同优先级就绪队列有其他线程,那么进行切换
        else if ((thread_ptr -> tx_ready_next != thread_ptr) &&
                 (thread_ptr -> tx_priority == thread_ptr -> tx_preempt_threshold))
        {
        
            /* There is another thread at this priority, make it the highest at
               this priority level.  */
               #def 就绪队列头部指向下一个线程,同时相当于当前执行线程移动到了队列尾部
            _tx_thread_priority_list[thread_ptr -> tx_priority] =  thread_ptr -> tx_ready_next;
	
            /* Designate the highest priority thread as the one to execute.  Don't use this 
               thread's priority as an index just in case a higher priority thread is now 
               ready!  */
               #def 选出新的执行线程
            _tx_thread_execute_ptr =  _tx_thread_priority_list[_tx_thread_highest_priority];

            /* Set the status to true to indicate a preemption is going to take
               place.  */
            status =  TX_TRUE;
        }
    }

    /* Restore previous interrupt posture.  */
    TX_RESTORE

    /* Return to caller.  */
    return(status);
}
发布了41 篇原创文章 · 获赞 2 · 访问量 3255

猜你喜欢

转载自blog.csdn.net/qq_45683435/article/details/104180755