互斥体与任务调度
当两个需要使用同一个共享资源的任务优先级不同时,高优先级会在低优先级任务刚释放互斥体时打断低优先级任务。但当两个任务优先级相同时,任务二不会在任务一刚释放互斥体时马上抢占,而会等待任务一时间片执行完后再执行,此时会产生如下一种情况,
即当任务二释放互斥体后的时间片执行完前又开始了第二次循环,从而再次获取互斥体,此时会导致切换到任务一后,任务一无法得到互斥体而再次进入阻塞,从而任务二继续执行。
为了解决这个问题应采用调用taskYIELD() 接口的方法,即在释放互斥体后直接调度任务调度器。
例程如下:
void vFunction( void *pvParameter )
{
extern SemaphoreHandle_t xMutex;
char cTextBuffer[ 128 ];
TickType_t xTimeAtWhichMutexWasTaken;
for( ;; )
{
/* Generate the text string – this is a fast operation. */
vGenerateTextInALocalBuffer( cTextBuffer );
/* Obtain the mutex that is protecting access to the display. */
xSemaphoreTake( xMutex, portMAX_DELAY );
/* Record the time at which the mutex was taken. */
xTimeAtWhichMutexWasTaken = xTaskGetTickCount();
/* Write the generated text to the display – this is a slow operation. */
vCopyTextToFrameBuffer( cTextBuffer );
/* The text has been written to the display, so return the mutex. */
xSemaphoreGive( xMutex );
/* If taskYIELD() was called on each iteration then this task would only ever
remain in the Running state for a short period of time, and processing time
would be wasted by rapidly switching between tasks. Therefore, only call
taskYIELD() if the tick count changed while the mutex was held. */
if( xTaskGetTickCount() != xTimeAtWhichMutexWasTaken )
{
taskYIELD(