Компоненты и технологии • №2 '2011 компоненты



Pdf көрінісі
бет86/129
Дата28.09.2023
өлшемі4.1 Mb.
#478975
1   ...   82   83   84   85   86   87   88   89   ...   129
Kurniz

xSemaphoreTake() было указано конечное 
время тайм-аута, «зависания» задачи не про-
изойдет. Вместо этого действия с ресурсом, 
выполняемые внутри функции, никогда 
не будут произведены, что также являет-
ся недопустимой ситуацией.
Когда программа проектируется так, что 
операции захват/освобождение мьютекса яв-
ляются вложенными, следует использовать 
рекурсивные мьютексы:
xSemaphoreHandle xRecursiveMutex;
/* ... */
xRecursiveMutex = xSemaphoreCreateRecursiveMutex();
/* ... */
/* Функция, реализующая задачу. */
void vTask(void *pvParameters) {
for (;;) {
/* Захват мьютекса */
xSemaphoreTakeRecursive( xRecursiveMutex, portMAX_DELAY );
/* Действия с ресурсом */
/* ... */
/* Вызов функции, которая выполняет операции с этим же 
ресурсом. */
vSomeFunction();
/* Действия с ресурсом */
/* ... */
/* Действия с ресурсом закончены. Освободить мьютекс. */
xSemaphoreGiveRecursive( xRecursiveMutex );
}
}
/* Функция, которая вызывается из тела задачи vTask*/
void vSomeFunction(void) {
/* Захватить тот же самый мьютекс.
При этом состояние мьютекса никоим образом не изменится.
Задача не заблокируется, действия с ресурсом внутри этой 
функции будут выполнены. */
if (xSemaphoreTakeRecursive( xRecursiveMutex, portMAX_DELAY 
) == pdTRUE ) {
/* Действия с ресурсом внутри функции */
/* ... */
/* Освободить мьютекс */
xSemaphoreGiveRecursive( xRecursiveMutex );
}
}
В этом случае программа будет работать 
корректно. При повторном захвате мьютекса 
API-функцией xSemaphoreTakeRecursive() за-
дача не перейдет в блокированное состояние, 
и эта же задача останется владельцем мью-
текса. Вместо этого увеличится на единицу 
внутренний счетчик, который определяет, 
сколько операций «захват» было применено 
к мьютексу, действия с ресурсом внутри функ-
ции vSomeFunction() будут выполнены, так 
как задача vTask остается владельцем мьютек-
са. При освобождении мьютекса (при вызове 
API-функции xSemaphoreGiveRecursive()
из тела одной и той же задачи внутренний 
счетчик уменьшается на единицу. Когда этот 
счетчик станет равен нулю, это будет озна-
чать, что текущая задача больше не являет-
ся владельцем мьютекса и теперь он может 
быть захвачен другой задачей.
Таким образом, каждому вызову API-
ф ун к ц ии xSemaphoreTakeRecursive() 
внутри тела одной и той же задачи дол-
жен соответствовать вызов API-функции 


Достарыңызбен бөлісу:
1   ...   82   83   84   85   86   87   88   89   ...   129




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет