Показать сообщение отдельно
Старый 03.08.2014, 13:39   #2900
Paul Kellerman
Gold Member
 
Регистрация: 25.06.2005
Адрес: F000:FFF0
Сообщений: 1,830
По умолчанию

kravets, проблема рандомизации доступа к ресурсу с использованием мьютекса решилась.

В классике каждый поток перед доступом к ресурсу пытается захватить мьютекс и если не
получается уходит в спячку, пока мьютекс не освободится и система отдаст мьютекс потоку.
Код:
if WaitForSingleObject(ResMutex,INFINITE) = WAIT_OBJECT_0 then
  begin
    .
    < работа с ресурсом >
    .
    ReleaseMutex(ResMutex);
  end;
Поток в случае занятости мьютекса непрерывно пассивно ждет, пока система не выберет его.
Система отслеживает время непрерывного ожидания и при освобождении мьютекса выбирает
тот поток, который дольше всех ждал (при равных приоритетах). А нам нужен случайный выбор.

Ну так давайте спутаем все карты системе и будем ждать не непрерывно, а случайно-дискретно.

Код:
flag:= False;
while not(flag) do
  begin
    dt:= 10 + 20 * Random;
    if WaitForSingleObject(ResMutex, dt) = WAIT_OBJECT_0 then flag:= True;
  end;
if (flag) then
  begin
    .
    < работа с ресурсом >
    .
    ReleaseMutex(ResMutex);
  end;
Из-за прерывистого ожидания со случайными интервалами системе приходится выбирать наугад.

Минус метода - низкое быстродействие, но мне и не нужно быстро. Потоки в среднем раз в секунду
обращаются к ресурсу. По сути получилась спин-блокировка с ожиданиями в течение случайных dt.

Протестировал в имитационной модели. Статистические показатели отлично сходятся с расчетными.

Последний раз редактировалось Paul Kellerman; 04.08.2014 в 05:56.
Paul Kellerman вне форума  
Реклама