Форум: "Прочее";
Текущий архив: 2009.06.14;
Скачать: [xml.tar.bz2];
ВнизВопрос по дедлокам. Найти похожие ветки
← →
Дмитрий Белькевич (2009-03-31 00:33) [0]Стоит ли на них строить нормальную логику работы приложения, или их нужно избегать всеми возможными методами?
← →
Хибл Герзмаев (2009-03-31 00:46) [1]что такое дедлок ?
← →
DVM © (2009-03-31 00:59) [2]как можно строить логику на дедлоках?
← →
Коммуноцентрист1 (2009-03-31 01:14) [3]
> Стоит ли на них строить нормальную логику работы приложения
нет :)
> или их нужно избегать всеми возможными методами?
нужно, но, и как в любом хорошем деле, главное, не расшибить лоб
← →
Коммуноцентрист1 (2009-03-31 01:23) [4]похоже, нулевая шишка уже есть, раз вопрос.
опишите ситуацию, на сухой теории рассказывать можно, но неэффективно
← →
Юрий Зотов © (2009-03-31 03:28) [5]Дедлок (если, конечно, он действительно дедлок, а не просто ожидание) блокирует работу двух (как минимум) потоков, и из этого взаимного клинча их даже еще одним потоком не вышибить. Какую на этом можно построить логику приложения?
← →
oxffff © (2009-03-31 04:24) [6]
> Дмитрий Белькевич (31.03.09 00:33)
> Стоит ли на них строить нормальную логику работы приложения,
> или их нужно избегать всеми возможными методами?
Deadlock - это определеноого рода ситуация ситуация.
И если есть арбитр(еще один поток если хотите), который идентифицирует такую ситуацию и разрешает ее.
Почему нет?
← →
SPeller © (2009-03-31 04:28) [7]
thread1 thread2
WaitForSingleObject(thread2)
SendMessage(thread1)
Тут уж только потоки уничтожать насильно. Какую полезную логику тут можно построиь? :) Такого вообще не должно быть в нормальной программе.
← →
KSergey © (2009-03-31 07:30) [8]> Юрий Зотов © (31.03.09 03:28) [5]
> из этого взаимного клинча их даже еще одним потоком не вышибить.
> Какую на этом можно построить логику приложения?
Стоп-кран?
← →
SPeller © (2009-03-31 08:19) [9]а может, имеется ввиду некто "дедло"?
← →
Виталий Панасенко (2009-03-31 09:07) [10]Если использовать по крайней мере две транзакции(компонента): длинную читающую, короткую для изменения данных, то шансов получить "смертельные объятия" практически нет...
← →
SPeller © (2009-03-31 10:14) [11]MultiReaderSingleWriter
← →
Palladin © (2009-03-31 10:24) [12]Лучше строить логику на AV :)
← →
Sergey Masloff (2009-03-31 15:00) [13]Palladin © (31.03.09 10:24) [12]
>Лучше строить логику на AV :)
Золотые слова
← →
oxffff © (2009-03-31 15:52) [14]
> Sergey Masloff (31.03.09 15:00) [13]
> Palladin © (31.03.09 10:24) [12]
> >Лучше строить логику на AV :)
> Золотые слова
Прошу в студию доказательства однонаправленности понятий deadlock и AV.
← →
Alkid © (2009-04-01 10:24) [15]
> Юрий Зотов © (31.03.09 03:28) [5]
>
> Дедлок (если, конечно, он действительно дедлок, а не просто
> ожидание) блокирует работу двух (как минимум) потоков, и
> из этого взаимного клинча их даже еще одним потоком не вышибить.
> Какую на этом можно построить логику приложения?
Юр, ты разве не понимаешь? Дедлок - это высокоэффективная замена бесконечного пустого цикла! И если цикл потребляет процессор, то дедлок - нет. 100% экономия ресурсов! Причём, если цикл вводит в ступор только один поток, то дедлок - два и более! Это же повышение эффективности до 200%! И даже больше!
> Palladin © (31.03.09 10:24) [12]
> Лучше строить логику на AV :)
+1
Шутки шутками, а некоторые альтернативно одарённые программисты умудрялись широко использовать исключения для возврата значений из функций.
← →
KSergey © (2009-04-01 10:37) [16]> Alkid © (01.04.09 10:24) [15]
> умудрялись широко использовать исключения для возврата значений из функций.
или для перехода в конец функции, вместо goto.
← →
clickmaker © (2009-04-01 10:39) [17]> или для перехода в конец функции
да здесь-то как раз нормально. Логика на исключениях выглядит иногда красивей, чем бесконечные вложенные ифы, особенно, если память много раз подо что-то выделяется
← →
Alkid © (2009-04-01 11:05) [18]
> clickmaker © (01.04.09 10:39) [17]
> да здесь-то как раз нормально. Логика на исключениях выглядит
> иногда красивей, чем бесконечные вложенные ифы, особенно,
> если память много раз подо что-то выделяется
Не нормально. Исключения не должны использоваться как штатный инструмент для передачи управления.
← →
clickmaker © (2009-04-01 11:07) [19]> Исключения не должны использоваться как штатный инструмент
> для передачи управления
да кто сказал?
если у меня сложная форма с кучей валидаторов - лестница из ифов, уходящая за горизонт будет лучше?
← →
oxffff © (2009-04-01 12:09) [20]
> Юрий Зотов © (31.03.09 03:28) [5]
> Дедлок (если, конечно, он действительно дедлок, а не просто
> ожидание) блокирует работу двух (как минимум) потоков, и
> из этого взаимного клинча их даже еще одним потоком не вышибить.
> Какую на этом можно построить логику приложения?
Не все так печально.
1. WaitForMultipleObjects,
2 .WaitForSingleObjectEx + Alertable + QueueUserAPC
3. WaitForMultipleObjectsEx + Alertable+ QueueUserAPC
← →
oxffff © (2009-04-01 12:14) [21]Мне вообще не понятно, почему стали заменять понятие deadlock на механизм исключений. И даже стали выдавать баллы.
Убежден в пригодности и полезности того и другого.
Но это два совершенно разных понятия.
Deadlock может присутствовать в логике.
Исключения могут присутствовать для логики.
← →
DVM © (2009-04-01 12:17) [22]
> Alkid © (01.04.09 11:05) [18]
> Не нормально. Исключения не должны использоваться как штатный
> инструмент для передачи управления.
Нормально, одно из предназначения исключений как раз и есть отделение места возникновения ошибки от места ее обработки.
← →
SPeller © (2009-04-01 13:28) [23]А я думал что AV и исключения - это немного разные вещи
← →
Дмитрий Белькевич (2009-04-01 13:53) [24]Тема начала разрастаться... Извиняюсь за немного неверную поставновку проблемы. Имеются в виду не сами deadlock"и, а их отлов. Можно ли строить нормальную логику приложения на отлове no wait deadlocks и повторении действий.
Deadlock"и всё таки ближе к av или к исключению?
← →
Дмитрий Белькевич (2009-04-01 14:04) [25]Не вижу ничего плохого в использование исключений в логике работы. Возраващать нормальные результаты из функции через исключение, наверно, не стоит. Но возвращать исключительные ситуации - вполне можно.
← →
test © (2009-04-01 14:10) [26]Дмитрий Белькевич (01.04.09 13:53) [24]
AV == access violation исключение
av == исключение
deadlock взаимное блокирование потоков друг другом, само по себе ошибку не вызвает.
Какой то странный у тебя вопрос ИМХО...
← →
KSergey © (2009-04-01 14:11) [27]> Дмитрий Белькевич (01.04.09 13:53) [24]
> Имеются в виду не сами deadlock"и, а их отлов. Можно ли строить нормальную логику приложения на отлове no wait deadlocks и повторении действий.
Растолкуйте своё понимание термина deadlock, плиз. В моём понимании - это именно непредвиденные (не запланированные) ситуации, в котороых 2 объекта взаимноблокируются так, что если их и можно разблокировать - то только сторонним участником взаимоотношений. О котором, возможно, не подумали про проектировании, и тогда только убить все приложение остается.
Если же по дизайну приложения есть два цикла, котрые запланировано на определенных участках блокируют работу соседа - то это скоре просто получается межпоточная синхронизация, т.к. это по дизайну и не смертельно. deadlock"ов не возникает.
← →
Дмитрий Белькевич (2009-04-01 14:34) [28]Опишу проблему вообще, может другие идеи появятся.
Есть два разных по функциональости потока (потомки tthread).
Один периодически просыпается, открывает пишущую транзакцию (у неё nowait НЕ выставлен), и не закрывает её. Закрывается же она либо по тайм-ауту (внешним таймером), либо по достижении определенного количества циклов записи в базу. Сделано так ускорения работы потока. Можно было бы транзакцию сразу же закрывать, после записи в базу, однако это замедляет работу (которая критична по времени) где-то раза в 2.
Когда работает один поток - то никаких особенных сложностей не возникает.
Добавляем второй поток. Поток, если бы ему не мешал первый, спать не должен. Он открывает пишущую транзакцию (у неё nowait выставлен), делает 3-4 запроса, закрывает транзакцию, уходит дальше в цикл, пока не "пробежит" все из нужных (2-3 миллиона) записей. Их список открыт (ibquery) в отельной (читающей) транзакции.
Так вот. Пока потоки работают отдельно - всё нормально. Как только они начинают работать вместе - во втором, само собой начинают вылазить nowait deadlock"и.
Отлавливаю их во втором потоке, откатываю транзакцию, усыпляю, делаю запрос снова.
Теперь опишу проблему.
Проблема в том, что при такой работе через некоторое время первый поток начинает медленно работать (в 10-50 раз). При этом сервер файрбёрда загружает одно из ядер на 100% (обычно - 50-80, если первый поток вообще работает). Приостанавливаю первый поток - загрузка падает почти до нуля.
Второй поток можно приостановить или вообще разрушить - ничего не меняется. Первый пока не пробовал - попробую.
Перезагружаю приложение - всё ок, всё работает. Пока опять оба потока одновременно к базе не лезут.
Вот такая весёлая история...
Да, FB - 2.1.1. На 2.0.3 - то же самое...
Может быть - какие-нибудь специальные инструменты есть для работы с FB?
Вроде же ничего особенного и не делаю...
Два потока всего лезут к одной таблице...
← →
Дмитрий Белькевич (2009-04-01 14:36) [29]>av == исключение
AV - это acess violation.
Исключение - это exception.
AV - это исключение, но исключение - это не AV. Не нужно путать.
← →
test © (2009-04-01 14:46) [30]Дмитрий Белькевич (01.04.09 14:36) [29]
>>AV - это исключение, но исключение - это не AV. Не нужно путать.
Вот с этого момента поподробнее, что не путать?
Тип исключения с исключением или что?
Дмитрий Белькевич (01.04.09 14:34) [28]
procedure TMyThread.PushTheButton;
begin
Button1.Click;
end;
procedure TMyThread.Execute;
begin
...
Synchronize(PushTheButton);
...
end;
← →
Дмитрий Белькевич (2009-04-01 14:53) [31]>Вот с этого момента поподробнее, что не путать? Тип исключения с исключением или что?
Не тип исключения, а принцип исключения. AV - это всегда ошибка. А exception - это только исключительная ситуация. Которая может быть и ошибкой. А может и не быть.
>Synchronize(PushTheButton);
Зачем мне это? Я где-то говорил, что один из потоков - VCL? Я же специально написал - оба - потомки tthread.
← →
Дмитрий Белькевич (2009-04-01 14:56) [32]Исключение - если уж на то пошло - это вообще класс и его модификации. В отличие от AV.
← →
test © (2009-04-01 15:05) [33]Дмитрий Белькевич (01.04.09 14:56) [32]
То есть ошибки != исключительные ситуации?
Дмитрий Белькевич (01.04.09 14:53) [31]
То есть их нужно как то разрулить без синхронизации между собой? Ну тогда мьютексы, сообщения и WaitForMultipleObjects не помогут.
← →
SPeller © (2009-04-02 03:01) [34]
> То есть ошибки != исключительные ситуации?
Ну чё пристал? AV это одна из составных частей понятия исключения. Если AV это стопудово исключение, то не каждое исключение - это AV.
Лучше по существу человеку подскажи, чем демагогию устраивать :)
← →
test © (2009-04-02 06:31) [35]SPeller © (02.04.09 03:01) [34]
Про синхонизировать опасный кусок я ему уже писал test © (01.04.09 14:46) [30].
← →
test © (2009-04-02 06:42) [36]SPeller © (02.04.09 03:01) [34]
Ну а какие могут быть еще варианты кроме синхронизации тем или другим способом опасного метода?
← →
Вариант (2009-04-02 06:50) [37]
> Дмитрий Белькевич (01.04.09 14:34) [28]
Вариантов может быть несколько. Если есть приоритетный поток (или выполняющий очень короткие и быстрые операции с базой), то его задача дать знать другому о необходимости "освободить базу", то есть завершить активную транзакцию и ждать команды на продолжение потока, что достигается синхронизацией например через событие для потока, которым надо управлять или другими способами (мне просто видится проще синхронизация на событии (Event) в данном случае, транзакции у обоих потоков "ждущие").
Или более простой на мой взгляд вариант - в базу пишет один поток, просто он имеет очередь запросов приоритетную и обычную. Или даже одну очередь - это уже по условиям задачи...
← →
test © (2009-04-02 06:55) [38]Вариант (02.04.09 06:50) [37]
Если в момент получения события второй поток надолго сидит в какой нибудь процедуре, то событие он получит как бы потом.
← →
Вариант (2009-04-02 07:03) [39]
> test © (02.04.09 06:55) [38]
Да, например он пишет в базу - ну так пусть закончит корректно запись и потом получит событие. Это почти при любом способе синхронизации так, когда поток уже скажем захватил разделяемы ресурс.
Кстати я вижу это несколько иначе, чем обычная сигнализация событий. Событие установлено изначально - то есть оно разрешает потоку писать, а вот перед записью стоит WaitForXXX с тайм-аутом=0, по тай-ауту активная транзакция завершается и тайм-аут меняется на INFINITE/ А если вышел из функции по WAIT_OBJECT_- то значит можно продолжать писать в базу. Ну а второй поток просто висит в ожидании на транзакции, как первый завершил свою транзакцию, второй начал свою... Но как я писал выше, вариантов исполнения может быть куча. Я бы может писал бы и одним потоком с очередями запросов... Надо смотреть конкретные условия задачи
← →
test © (2009-04-02 07:13) [40]Вариант (02.04.09 07:03) [39]
В любом случае надо сигнализировать потоку что процедура занята, переменной или сообщением или блоком синхронизации. Зачем выдумывать лисапеды если есть стандартные средства Дельфи Synchronize например, у него еще парочка таких же, но под дедлоком обычно подразумевают блокировку в разных местах, например первый открыл файл и не отдает, в это время второй открыл другой файл и ждет когда можно будет записать в файл первого, а первый ждет когда можно будет записать в файл второго, и все ждут пока программу не рубанут.
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2009.06.14;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.007 c