Конференция "Прочее" » Vista и CriticalSection
 
  • Добежал (23.10.08 14:04) [20]

    > Впрочем, я придумал как изменю ситуацию. Ведь можно просто
    > запомнить позицию устройства в списке. Потом по входу в
    > критич. секцию просто проверить тоже ли самое устройство
    > находится на этом же месте, если да - то обновить


    посмотрел код, вспомнил. Блин, фигово.

    Дело в том, что при сканировании другому модулю кое-что отсылается, и от него может вернуться ответ... Но не сразу и этого ответа никто не ждет тут же.

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

    Конечно, можно никакие уведомления не отсылать во время сканирования. Сначала просканировать, ЗАПОМНИТь какие уведомления надо отослать, потом зайти в критическую секцию, изменить данные устройства, выйти из секции, послать уже уведомление... Бррр.... код становится очень нечитаемым ;(((
  • guav © (23.10.08 14:06) [21]
    > [19] Добежал   (23.10.08 13:56)
    > Не должно. Я везде использую дельфовые TThreadList - мне
    > так удобнее.

    Разница в том, что в виндовый Slist добавление или удаление элемента происходит вообще без блокировки.

    Кажется, есть идея что тебе нужно. Своя КС у каждого устройства.
  • Добежал (23.10.08 14:14) [22]

    > Своя КС у каждого устройства


    да, сейчас обдумываю в том же направлении. Но много косяков. Рассмотрим тоже самое удаление:

    Должен быть заблокирован список, потом выбрано устройство, заблокировано устройство... А если устройство в это время занято? В общем, боюсь взаимных блокировок, если сейчас все переделывать...
  • Добежал (23.10.08 14:15) [23]
    Самое простое пока вот что придумал. Если неактивному потоку нужен доступ к секции, то где-нибудь с помощью InterlockedIncreament выставлять флаг. Если по выходу из секции активный поток видит что флаг выставлен - принудительно себе делает sleep... Костыль, но должно работать, хотя и не нравится мне это.
  • Добежал (23.10.08 14:16) [24]

    > Разница в том, что в виндовый Slist добавление или удаление
    > элемента происходит вообще без блокировки


    я рад. Но неработа программы на windows 2000 категорически недопустима. Строго говоря, нужен и win 9x.
  • KSergey © (23.10.08 14:18) [25]
    > guav ©   (23.10.08 13:49) [18]
    > Когда КС используется правильно, на ней вообще блокировки редко происходят.

    Редко или ненадолго? Что тут имелось в виду?
  • guav © (23.10.08 14:19) [26]
    > [22] Добежал   (23.10.08 14:14)
    > Должен быть заблокирован список, потом выбрано устройство,
    > заблокировано устройство...

    Можешь покопать в направлении поискать готовый код lock-free списка. http://www.google.com.ua/search?hl=ru&q=lock-free+list&meta=

    An interlocked singly linked list (SList) eases the task of insertion and deletion from a linked list. SLists are implemented using a nonblocking algorithm to provide atomic synchronization, increase system performance, and avoid problems such as priority inversion and lock convoys.

    SLists are straightforward to implement and use in 32-bit code. However, it is challenging to implement them in 64-bit code because the amount of data exchangeable by the native interlocked exchange primitives is not double the address size, as it is in 32-bit code. Therefore, SLists enable porting high-end scalable algorithms to Windows.
  • guav © (23.10.08 14:20) [27]
    > [25] KSergey ©   (23.10.08 14:18)

    Я под блокировкой подразумевал захват несколькими потоками одновременно.
    Завхат КС одним потоком - без блокировки. Захват вторым, когда первый держит - блокировка, которая должна быть редкостью.
  • Добежал (23.10.08 14:25) [28]

    > Можешь покопать в направлении поискать готовый код lock-
    > free списка


    а смысл? Только в том, что insert делается без блокировки? нафиг мне это надо...
  • guav © (23.10.08 14:35) [29]
    > [28] Добежал   (23.10.08 14:25)
    > нафиг мне это надо...

    Ты ж в [22] боишься дедлоков,нет?
  • Добежал (23.10.08 14:41) [30]

    > Ты ж в [22] боишься дедлоков,нет?


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

    Поэтому при вставке мне все равно надо заблокировать список и пробежаться по нему для поиска такого же адреса.

    Короче сделал так, интересно насколько это приемлимо, выглядит как обход оптимизации windows ;)

    InterlockedIncrement(iPlace);
    Place.LockList;
    try
    ...  работа...
    finally
     Place.UnlockList;
     InterlockedDecrement(iPlace);
    end;



    А у активного потока есть что-то типа:

    .....
    finally
     Place.UnlockList;
     while iPlace > 0 then sleep(1);
    end;



    Бред? Вроде элегантно с одной стороны, с другой выглядит как чистый костыль, обходящий оптимизацию планировщика висты...
  • han_malign © (23.10.08 14:55) [31]

    > а это более приоритетная операция, чем изменение свойств
    > устройства во время сканирования

    - с какой радости она более приоритетная, если - до окончания сканирования и обновления - блокируется?
    а разруливается все, как всегда, элементарным конечным автоматом

    Idle, Processing, Changed, Deleting

    сканер:
    Idle
    |

    Changed
    ==>

    Processing
    Processing
    = update =>

    Idle
    |

    Changed
    =?=>

    Idle
    |

    Deleting
    ==> <Null>



    менеджер:
    <Null> =>

    Idle
    Idle
    |

    Processing
    = change =>

    Changed
    Processing
    ==>

    Deleting
    |

    Idle
    ==> <Null>

  • Добежал (23.10.08 14:59) [32]

    > - с какой радости она более приоритетная, если - до окончания
    > сканирования и обновления - блокируется?


    приоритетная не по времени, а по конечному результату.

    То есть, если в процессе сканирования выяснится что устройство работает, а уведомление придет что оно должно быть выключено - значит, оно должно быть выключено.
  • guav © (23.10.08 16:29) [33]
    Что будет вообще лучше - "честная" очерёдность или вообще дать приоритет другому потоку ?
  • Добежал (23.10.08 17:32) [34]
    не понял вопроса.
  • guav © (23.10.08 19:02) [35]
    Честная очередь:
    кто первый захотел захватить мьютекс, тот его первый хватает.
    в результате получится, что работают по очереди.

    Дать приоритет другому:
    это:
    while true do
    begin
     TestList.LockList ;
     sleep(200);
     TestList.UnlockList ;
    end;
    ме будет выполняться, пока другому потоку нужен список
  • oxffff © (23.10.08 19:22) [36]
    Еще есть функция SwitchToThread.

    while true do
    begin
    TestList.LockList ;
    sleep(200);
    TestList.UnlockList ;
     SwitchToThread;
    end;
  • Добежал (27.10.08 10:57) [37]
    SwitchToThread тоже не работает в win9x.
  • Cobalt © (27.10.08 14:46) [38]
    Автору: почитай статью:
    DTF.RU - То, что вам никто не говорил о многозадачности в Windows  www.dtf.ru/articles/read.php?id=39888

    Это к вопросу о том, почему "второй поток умудряется висеть по десятку секунд!"

    Может быть натолкнет на какую мысль.
  • Добежал (27.10.08 18:18) [39]

    > Это к вопросу о том, почему "второй поток умудряется висеть
    > по десятку секунд!"
    >
    > Может быть натолкнет на какую мысль


    Доброе утро.
    На какую еще мысль? Причины, почему поток висит по десятку секунд я описал еще в самом начале ветки. Вопрос в другом - как добиться более равноправного доступа к критической секции.
 
Конференция "Прочее" » Vista и CriticalSection
Есть новые Нет новых   [134444   +21][b:0][p:0.001]