[Previous] [Next]

Взаимоблокировки

Взаимоблокировки (deadlocks) могут возникать при недостаточно корректном использовании спин-блокировок, объектов событий, мьютексов и семафоров, то есть практически любых синхронизационных примитивов. Даже объекты потоков могут дать взаимоблокировку, если потоки ожидают окончания работы друг друга. Взаимоблокировки легко возникают там, где происходит состязание нескольких потоков за владение несколькими ресурсами, причем каждому из них нужно несколько единиц ресурсов одновременно — и это при том, что каждый поток может получить отказ при попытке доступа к каждому из ресурсов.

Разумеется, каждый случай такой "неразберихи" уникален, тем более, что здесь может оказывать влияние еще один квази-ресурс — приоритет. Тем не менее, можно выделить три направления решения этой проблемы.

Во-первых, можно указывать максимальное время ожидания (параметр Timeout) при вызовах KeWaitForXxx. Этот способ не так хорош, поскольку не устраняет логическую ошибку в алгоритме работы драйвера, однако, дает локальное решение проблемы.

Второй способ состоит в пере-разбиении или укрупнении ресурсов, что сокращает "количество поводов" для разногласия.

В-третьих, можно заставить все потоки производить получение ресурсов в одном и том же порядке. Скажем, два потока имеют в своем распоряжении по одному ресурсу и начинают спор о владении вторым (он, разумеется, находится у конкурента). Проблемы не возникло бы, если оба потока решили, кому владеть первым ресурсом, победителю достался бы и второй, после чего он освободил бы оба ресурса, предоставив их конкуренту.