Re[12]: lock с приоритетом
От: Jolly Roger  
Дата: 13.02.11 14:29
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Только не забывайте, что это всего лишь набросок, который мной не то что не тестировался — даже не запускался, да и не анализировался. Будьте осторожны.


Так и есть, как минимум одна дырка — может получиться, что Enter поместит поток в очередь сразу после того, как из него выйдет последний владелец, как результат — всё повиснет. Проще всего поправить поместив всё тело методов Enter (кроме двух последних строк) и Leave внутрь lock (innerLock), заодно заменив LockFreeStack обычным стеком или списком.

S>В плане "зачем" — иначе и не скажешь, как приоритезация входа в крит.секцию.


Всё-таки на всякий случай прочтите здесь
"Нормальные герои всегда идут в обход!"
Re: lock с приоритетом
От: vf  
Дата: 13.02.11 17:50
Оценка:
Здравствуйте, 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)
}
Re[2]: lock с приоритетом
От: vf  
Дата: 13.02.11 18:09
Оценка:
Или так...

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();
}
Re[3]: lock с приоритетом
От: vf  
Дата: 13.02.11 18:14
Оценка:
Здравствуйте, 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>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.