Как контролировать, какой ожидающий поток получает следующую блокировку? - PullRequest
0 голосов
/ 10 августа 2011

В стандартных классах синхронизации C # (например, Monitor), если несколько потоков ожидают разблокировки какого-либо объекта, никто не может предсказать, какой поток получит следующую блокировку.

Я хочу назначить приоритет всем ожидающимпотоки, поэтому они получают блокировки в соответствии с этим приоритетом (если несколько потоков ожидают разблокировки).

Как я могу это реализовать?

1 Ответ

1 голос
/ 10 августа 2011

Самый простой подход, если не слишком много уровней приоритета, состоит в том, чтобы иметь основную блокировку плюс Int32 для каждого уровня, кроме самого высокого, указывающего, сколько задач с более высоким приоритетом ожидает.Задача, которая хочет получить блокировку, будет заблокирована. Инкрементируйте счетчик для каждого более низкого приоритета, затем дождитесь основной блокировки и проверьте, ожидали ли какие-либо задачи с более высоким приоритетом.Если это так, он освободит и снова получит главный замок.В противном случае Interlocked.Decrement счетчики задач с более низким приоритетом, использовать ресурс и снять основную блокировку.Если подпрограмма перестает получать блокировку, она должна уменьшить счетчики задач с более низким приоритетом.

При таком подходе потребуются дополнительные издержки при выполнении задач с более низким приоритетом при получении и снятии основной блокировки при выполнении задач с более высоким приоритетомхотел, но это не должно быть слишком плохо.Кроме того, порядок, в котором задачи с более низким приоритетом получают блокировку после выполнения задачи с более высоким приоритетом, может быть фактически случайным.Таких проблем можно избежать, добавив блокировку для каждого уровня приоритета, и заставив каждую задачу получить блокировку для своего уровня после операций Interlocked.Increment;как и раньше, декремент должен происходить, когда блокировка либо получает ресурс, либо прекращает его ожидание.

...