Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Delphi: WinAPI и системное программирование > Существует ли механизм вытеснения из потокозащиты? |
Автор: Spike 13.12.2012, 20:36 |
Ребят, подскажите, куда копать: Есть данные, используемые разными потоками, одним очень критичным ко времени (как бы RealTime, далее RTT) и одним или несколькими вспомогательными, которые могут и подождать. Думается, что было бы красиво, если RTT когда ему приспичит мог бы вытеснить остальные из защищенного участка, пусть даже ценой потери вспомогательными потоками данных. Существует ли какой-то механизм для такого взаимодействия потоков? |
Автор: Poseidon 13.12.2012, 20:49 |
Чем не устраивает повышение приоритета? Приостановка вспомогательных на время выполнения основного? Или я не понял значение слова "вытеснить"? |
Автор: Spike 13.12.2012, 21:28 |
имеется ввиду "вытеснение" из участка потокозащищенного кода, т.е. ситуация, когда второстепенный поток уже в защищенном коде, а главному в это время нужно срочно туда "вломиться" |
Автор: bems 13.12.2012, 23:21 |
А что делать если второстепенный поток уже наполовину изменил общие данные? |
Автор: Spike 13.12.2012, 23:41 |
Допустим что второстепенный поток ничего не меняет, ему доступно только чтение. |
Автор: northener 14.12.2012, 00:49 |
Два ваших последних вопроса наводят меня на мысль, что вы пытаетесь сделать из ОС Windows ОС реального времени. Удачи. :( |
Автор: bems 14.12.2012, 01:02 | ||||
тогда не нужно читать в локе. добавь общим данным два поля: номер версии данных которая начала записываться (FUpdatingVersion) и номер версии данных которая полностью записана (FUpdatedVersion). Пишущий поток перед записью делает InterlockedIncrement(FUpdatingVersion), потом изменяет данные, потом делает InterlockedIncrement(FUpdatedVersion). Если пишущий поток тоже может быть не один, то всё это включая оба вызова InterlockedIncrement делает внутри лока. Читающий поток без всяких локов запоминает FUpdatingVersion читает сами данные и потом читает FUpdatedVersion. Если FUpdatingVersion <> FUpdatedVersion значит он скопировал себе данные, с которыми в тот момент работал пишущий поток, и обрабатывать их нельзя. Пусть или повторяет попытку позже, или что ты там предусмотришь для этого случая. Если версии равны, значит данные прочитались целостно.
|
Автор: Spike 14.12.2012, 01:08 | ||
блин, очень трудно не упустив сути не залезть в дебри.... .... я не совсем правильно выразился, второстепенный поток в особом режиме работы приложения (когда от RTT требуется минимум задержек) может только читать. пока думал как все это описать пришла жосткая мысль: изменять данные по требованию RTT, а для чтения сделать обработку ошибок преобразования данных - но это дюже не по феншую.... RTT - является основным по функционалу потоком процесса, занимается он только вычислениями и внешними коммуникациями. GUI, естественно, работает в другом потоке, есть еще пара потоков с вспомогательными вычислениями. Т.е. прибить их никак. Проблема как раз в том, что есть вероятность засыпания RTT при доступе в защищенную область из-за уже открытой "сессии" другого потока. но, ребят, мы отклонились от темы: я просто спросил, существуют ли в природе (подмножество Windows )))) механизмы "вытеснения" из защищенного кода (нечто вроде критической секции) для которой есть приоритетный поток, который может "выгнать" любой другой. Нет этого в винде и ладно, по-другому решим...
чх нисколько не полезный пост ![]() во-первых, вопрос я задал лишь один, во-вторых прям уж такого реального реального времени мне не нужно, есть внешние средства для выреальнивания (или отреальнивания), в-третьих, коль уж тут такой вопрос, можно и похоливарить по теме RT (но, пожалуйста, не здесь), в-четвертых, удача - для неудачников ))) Добавлено через 1 минуту и 50 секунд крутяк! сегодня как раз на статью про атомарные операции наткнулся, это уже кое-что.... |
Автор: bems 14.12.2012, 01:17 |
да, и попробуй еще класс TMultiReadExclusiveWriteSynchronizer из SysUtils |
Автор: Spike 14.12.2012, 01:24 | ||
Ну судя по описанию это очень хорошо ![]()
Хотя "вытеснения" тут тоже нет, оптимизируется только чтение. Что все равно хорошо! |
Автор: northener 14.12.2012, 01:33 |
Это где? Добавлено через 2 минуты и 19 секунд Это уж мы оценим в будущем. |
Автор: Spike 14.12.2012, 01:50 |
[T]winCAT, RTX VenturCom - это навскидку. Да только мне их не нужно, мне немного по-другому можно делать, без Hard RT. Да и вопрос был о другом ))) |
Автор: bems 14.12.2012, 01:55 | ||
нацарапал класс, иллюстрирующий идею
ну вот например http://www.directinsight.co.uk/products/venturcom/rtx.html |
Автор: Spike 14.12.2012, 02:01 |
bems, беспредельный респект и уважуха!!! думаю как это приладить чтоб было красиво |
Автор: Spike 20.12.2012, 21:11 | ||
Всем привет! Было не просто... проект не маленький и в-общем-то работающий, внедрение Interlocked-функций субъективно улучшило производительность (конечно, параллельно сделан небольшой рефакторинг и оптимизация). Да, поизучал, поэкспериментировал с TMultiReadExclusiveWriteSynchronizer - не совсем то что нужно, насколько я понял - если некий поток хочет что-то записать, он будет ждать пока читающие потоки закончат свои дела. С Interlocked-функциями интереснее - пишущий поток даже не думает что там кто читает, пишет когда нужно и все. Моя реализация аналогична примеру от bems. Для читающих потоков создается образ-копия данных, а по завершению создания образа проверяется версия, если не та - переделать. Пишущий поток просто ломится в данные, меняет их и увеличивает версию. Получилось красиво и универсально ![]() P.S.: вот еще полезное
|