![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
Poseidon |
|
||||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Ну да, реально проще наворотить с три короба кода, придумать крутые алгоритмы с переменными, сигнализированием, счетчиками, но ни за что не пользоваться Synchronize. А в чем разница, или поток будет крутить в холостую цикл, ожидая когда же нужная переменная примет нужное значение, что бы пойти дальше, или поток остановится, ожидая Synchronize? Это не решение, а один из вариантов. Если потоку надо "вбросить" данные в VCL и идти дальше (как в случае автора), то Queue подойдет. А если потоку надо работать с данными VCL, то тут нужна гарантия что кто-то другой (поток или даже сам пользователь) не поменял эти данные в процессе. А теперь самое интересное. У UKRtortik в Synchronize одна строчка кода, которая обрабатывается за долю секунды. Неужели блокировка потока на эту долю секунды и есть то самое "зависание" о котором пишет UKRtortik? Неужели если мы отправим в VCL неблокирующее сообщение вместо Synchronize, то поток не "зависнет"? Там по коду отчетливо видно, что поток посылает Get в сеть и ждет ответ. Вот это ожидание и есть причина. А Synchronize там вообще не при чем. Модератор: Давайте вернёмся к теме обсуждения. -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||
|
|||||
Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 26 Всего: 146 |
F7 & F8
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. ![]() |
|||
|
||||
PointerToNil |
|
|||
![]() Профиль Группа: Участник Сообщений: 108 Регистрация: 17.6.2013 Репутация: 3 Всего: 6 |
Poseidon> А если ситуация, когда потоку надо обратиться к VCL несколько раз подряд? Как без блокируещего метода и без бубна гарантировать, что предыдущее обращание завершилось?
это гарантируется тупо тем, что поток VCL только один и, естественно, обращения к нему выстраиваются в очередь (ну загляни в classes.pas что ли уже, если ссылки tl;dr) Poseidon> Т.е. если один поток отрабатывает критическую секцию, второй поток не ждет на входе в нее? Второй поток не простаивает? Это чем-то принципиально отличается от Synchronize? да. отличается по области применения. критические секции (или атомарный доступ к предложенным мной переменным-признакам или счетчикам) нужны для сериализации (очередизации) доступа к данным среди потоков-копий из одной группы/пула - они могут за эти данные конкурировать, например, пытаться одновременно "забрать" себе на обработку один очередной необработанный блок. а в ситуации как у ТС, когда "рабочий" поток уже обработал блок данных и он ему больше не нужен, поток следующего этапа (занимающийся выводом) может его спокойно (если этот поток в одном экземпляре) забирать, он должен только о его готовности узнать либо по переменной-признаку, либо по сообщению в своей очереди. без конкуренции потоков синхронизация гораздо проще (нет толкотни соседей по очереди) Poseidon> Ну да, реально проще наворотить с три короба кода, придумать крутые алгоритмы с переменными, сигнализированием, счетчиками да никаких "алгоритмов" тут нет! самое сложное тут - это
(обычно это успевают сделать за нас еще в Микрософте/Борлакадеро, и там у них внутри те же примитивные переменные и циклы) Poseidon> А в чем разница, или поток будет крутить в холостую цикл, ожидая когда же нужная переменная примет нужное значение, что бы пойти дальше, или поток остановится, ожидая Synchronize? предполагается, что "крутить цикл" будет ожидающий данных (пока еще не готовых) поток второго этапа (вывода и т.п.), а останавливать по Synchronize я не хочу потоки первого этапа ("рабочие"), к которым навалом других сырых данных в очереди ещё стоит (если вдруг наоборот, в очереди на вывод скопление образуется, то и крутить вхолостую ничего не придется) Poseidon>А если потоку надо работать с данными VCL, то тут нужна гарантия... да что же это такое то?!?! с данными VCL номинально разрешено работать только потоку VCL. к счастью, он у нас только один гарантий же от глупости программиста никакие волшебные классы/методы/функции никогда не дадут в частности, Synchronize блокирует только свой собственный поток (думаете, авторы VCL предполагали, что программист, только что послушно выполнив их рекомендации и вызвав правильный метод, может ТУТ ЖЕ СРАЗУ уйти в отрыв и с горя полезть в VCL напрямую, поэтому и решили это дело заблокировать?!? сорри за эмоции, если что) при этом Synchronize ничуть НЕ блокирует ВСЕ остальные потоки (вообще по-хорошему только сам поток может себя "поставить на паузу", как и закончить, хотя через winapi... но это не рекомендуется) Модератор: Давайте вернёмся к теме обсуждения. а без тредстартера основная тема все равно пока WaitingForSingleObject Это сообщение отредактировал(а) PointerToNil - 15.4.2014, 12:16 |
|||
|
||||
Poseidon |
|
||||||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Отлично. Поток отдает VCL данные, что бы VCL их применил, и идет дальше. А дальше нужно эти данные прочитать. Поток считывает данные, наивно предполагая, что предыдущий код их изменил. Но вот незадача, наредивый пользователь влез своими руками и поменил что-то. И получилось у нас, что поток считал уже не те данные, которые ожидались. Ах да, можно же нагородить кучу проверок, флагов, блокировок, но Synchronize использовать ну никак нельзя. "Это" - 10 строк кода в примитивной реализации. Synchronize займет одну.
PointerToNil, если есть желание обсудить никчемность Synchronize, можешь создать для этого отдельную тему. -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||||
|
|||||||
UKRtortik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 29 Регистрация: 24.3.2014 Репутация: нет Всего: нет |
Извините я возможно не заметил, ну где мне указали причину? |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
UKRtortik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 29 Регистрация: 24.3.2014 Репутация: нет Всего: нет |
а что с этим делать?
|
|||
|
||||
stanilar |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 9.2.2010 Репутация: нет Всего: нет |
Tесли HTTPSend - это Indy, то у ней может быть свой механизм потоков, с странным поведением которого вы и сталкиваетесь.
|
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
UKRtortik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 29 Регистрация: 24.3.2014 Репутация: нет Всего: нет |
![]() этого что недостаточно? |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
А покажи пинг того ресурса, куда отправляется Get.
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
PointerToNil |
|
|||
![]() Профиль Группа: Участник Сообщений: 108 Регистрация: 17.6.2013 Репутация: 3 Всего: 6 |
Poseidon, я все же сделаю еще одну попытку объяснить недопонятое, потому, что иначе затраченные нами обоими на этот разговор усилия оказываются совсем бесполезными. А так остаётся маленькая надежда.
Те приведенные 10 строк - вовсе не замена synchronize, они нужны для совсем другого случая - а именно, для сериализации доступа к данным между конкурирующими за них потоками (перечитайте абзац, где упоминается конкуренция). Там synchronize не применим никак, так как разбираться друг с другом должны несколько рабочих (неглавных) потоков! (обычно их число = числу ядер или *2 для гипертрединговой архитектуры). Участвует ли в этой конкуренции еще и главный (VCL) поток или нет - значения не имеет. Interlocked* функции (пример в тех 10 строках) - облегченная замена критическим секциям для случаев, когда нужна одноразовая атомарная операция с переменной/полем простого типа. А вот TThread.Queue - отличный вариант (как замена synchronize), я как раз за него! (если он есть в вашей версии дельфей) "без тредстартера основная тема все равно пока WaitingForSingleObject" - перевожу на русский: без тредстартера основная тема все равно пока зависла в ожидании одного объекта, т.е. тредстартера (это была попытка пошутить) BTW, собрал и запустил код тредстартера - никакие "подвисания" не проявились Это сообщение отредактировал(а) PointerToNil - 17.4.2014, 12:58 |
|||
|
||||
CynicRus |
|
||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 248 Регистрация: 31.5.2012 Репутация: нет Всего: 5 |
Яж тебе говорил - под отладчиком пошагово посмотри, где у тебя тормозит. Как пользоваться отладчиком? Можно заценить тут. |
||||
|
|||||
UKRtortik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 29 Регистрация: 24.3.2014 Репутация: нет Всего: нет |
а как понять из-за чего зависает в открадчике? Зависать начинает на этой строке:
|
|||
|
||||
PointerToNil |
|
|||
![]() Профиль Группа: Участник Сообщений: 108 Регистрация: 17.6.2013 Репутация: 3 Всего: 6 |
UKRtortik, тебе нужно найти строку в коде программы, исполнение которой тормозит
1 поставь breakpoint (F5) на первой после begin строке TNewThread.Execute 2 запусти программу (F9), в ней - свой тред, дождись срабатывания брейкпоинта (открытия экрана дельфи) 3 теперь жми F8 и следи за задержкой (между скрытием и новым появлением экрана дельфей, обычно это мерцание даже не успеваешь заметить) - многократно, пока не найдешь (или до выхода из метода) |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |