Jump to content
    

mutex - есть ли очередь?

Здравствуйте.

 

Сначала описание проблемы (ну или того что у меня просто не получается по незнанию) - есть две задачи, каждая из них может обращаться к разделяемому ресурсу, для поочередного доступа я использую mutex (на самом деле я просто изучаю FreeRTOS и пробую различные тесты для этого). Написал такой код:

 

void Task_1( void *pvParametrs ) 
{
    while(1)
    {
        xSemaphoreTake( mutex_1, portMAX_DELAY );
        
        LCD_ClearLine(LCD_LINE_6);
        LCD_ClearLine(LCD_LINE_7);
        LCD_DisplayStringLine(LCD_LINE_6, (uint8_t *)" TASK 1 ");
        
        vTaskDelay( 2000 / portTICK_RATE_MS );
        
        xSemaphoreGive( mutex_1 );
    }
}

void Task_2( void *pvParametrs ) 
{
    while(1)
    {
        xSemaphoreTake( mutex_1, portMAX_DELAY );
        
        LCD_ClearLine(LCD_LINE_6);
        LCD_ClearLine(LCD_LINE_7);
        LCD_DisplayStringLine(LCD_LINE_7, (uint8_t *)" TASK 2 ");
        
        vTaskDelay( 3000 / portTICK_RATE_MS );
        
        xSemaphoreGive( mutex_1 );
    }
}

 

Задача 1 и 2 имеют одинаковые приоритеты.

 

Так вот код в задаче 2, который находится за попыткой схватить семафор, никогда не выполняется. В 3х других RTOS с которыми я имел дело (TNKernel, CHibiOS, SMX) - такой-же код (ну со своим API естественно) работает нормально - то есть поочередно выполняется код task_1 и task_2 (задача стоит просто проверить работу mutex, поэтому не надо предлагать других методов выполнения этой простой задачи). Видимо в тех RTOS есть "очередь" на mutex - и если задача попыталась схватить, занятый mutex, то она встает в эту очередь и после освобождения mutex другой задачей первая его хватает. А в FreeRTOS такого получается нету?

 

Или я что то не правильно делаю?

 

P.S. если после xSemaphoreGive первую задачу отправить в сон (Delay) - то всторая задача все-же захватывает mutex и выполняет свой код и выполянется 2 задача постоянно - 1 уже не может схватить mutex (ну если 2 задачу в сон после xSemaphoreGive не отправлять тоже) - что вроде говорит что mutex работают, но без очереди.

 

Во внутренности очень не охото лезть - может уже кто сталкивался с таким.

 

Заранее благодарю за любые подсказки.

Share this post


Link to post
Share on other sites

Antonov,

 

У Вас как только одна из задач отдает мутекс, сразу же его и забирает.

Т.к. приоритеты равные у задач, то берёт мутекс та задача, которая шустрее(выигрывает в гонке).

 

Измените немного код: отдавайте мутекс до того, как вызывается шедулер.

 

Т.е.:

сперва

xSemaphoreGive( mutex_1 );,

а уж потом

vTaskDelay( 2000 / portTICK_RATE_MS );

 

В обоих тасках.

Share this post


Link to post
Share on other sites

Насколько я понимаю, xSemaphoreGive() в случае применения его к мутексу вызывает переключение контекста только в случае, если более высоприоритетная задача находится в ожидании этого мутекса. Функция xSemaphoreTake() также не вызывает переключения контекста, если мутекс не занят. Итого, при использовании его в подобной тестовой ситуации с одинаковым приоритетом задач без использования задержек и событий нужно как минимум воткнуть taskYIELD().

 

Думаю, что в реальной ситуации таких вопросов бы не возникло. Там скорее всего приоритет задач, использующих общий ресурс, разный. Либо есть задержки vTaskDelay(), либо работа с общим ресурсом происходит по событию.

 

Если ответить на вопрос про очередь задач задач, обратившихся за мутексом, то очереди здесь нет, но мутекс "помнит", что его ожидает задача с более высоким приоритетом и в этом случае при отдаче переключает контекст, а там уже планировщик разруливает, что же делать дальше.

Edited by SMaster

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...