Здравствуйте, Jolly Roger, Вы писали:
JR>Только не забывайте, что это всего лишь набросок, который мной не то что не тестировался — даже не запускался, да и не анализировался. Будьте осторожны.
Так и есть, как минимум одна дырка — может получиться, что Enter поместит поток в очередь сразу после того, как из него выйдет последний владелец, как результат — всё повиснет. Проще всего поправить поместив всё тело методов Enter (кроме двух последних строк) и Leave внутрь
lock (innerLock), заодно заменив LockFreeStack обычным стеком или списком.
S>В плане "зачем" — иначе и не скажешь, как приоритезация входа в крит.секцию.
Всё-таки на всякий случай прочтите
здесь
Здравствуйте, sergunok, Вы писали:
S>Такое есть в современном .NET?
S>Или нужно реализовывать самому?
1. Можно на это смотреть как на повышение приоритета потока для некоторого блока кода lock(sync), и наверное можно же так и сделать — перед локом повышать приоритет, после востанавливать.
2. Допустим приоритета 2, тогда наверное можно что нить замутить на двух объектах синхронизации — идея такая, что формируется две очереди ожидающих потоков, низко- и высокоприоритетная. Думая для этого можно использоват AutoResetEvent и Monitor. Что нить того что ниже. При желании думаю можно маштабировать на большее число приоритетов. Зато никаких самописных очередей.
void FromHighPriority()
{
lock(sync)
{
ActualMethod();
}
manualResetEvent.Set();
}
void FromLowPriority()
{
for(;;)
{
manualResetEvent.WaitOne();
if(Monitor.TryEnter(sync))
break;
}
ActualMethod();
Monitor.Exit(sync)
}
Или так...
private volatile static int highPriority;
void Method(int pripority)
{
for(;;)
{
autoResetEvent.WaitOne();
// потоки пытаются найти высокий приоритет
int oldhp = highPriority;
while(priority < oldhp && oldhp != Interlocked.Exchange(ref highPriority, priority))
oldhp = highPriority;
// кто-то сразу отсеивается
if(highPriority < priority)
continue;
// потоки с одинаковым самым высоким приоритетом пытаются схватить лок
if(Monitor.TryEnter(sync))
break;
}
// action
Monitor.Exit(sync)
highPriority = int.MaxValue;
autoResetEvent.Set();
}
Здравствуйте, vf, Вы писали:
vf>Или так...
vf>vf>private volatile static int highPriority;
vf>void Method(int pripority)
vf>{
vf> for(;;)
vf> {
vf> autoResetEvent.WaitOne();
vf> // потоки пытаются найти высокий приоритет
vf> int oldhp = highPriority;
vf> while(priority < oldhp && oldhp != Interlocked.Exchange(ref highPriority, priority))
vf> oldhp = highPriority;
вот здесь нужно дождаться всех потоков
vf> // кто-то сразу отсеивается
vf> if(highPriority < priority)
vf> continue;
vf> // потоки с одинаковым самым высоким приоритетом пытаются схватить лок
vf> if(Monitor.TryEnter(sync))
vf> break;
vf> }
vf> // action
vf> Monitor.Exit(sync)
vf> highPriority = int.MaxValue;
vf> autoResetEvent.Set();
vf>}
vf>