![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
PointerToNil |
|
|||
![]() Профиль Группа: Участник Сообщений: 108 Регистрация: 17.6.2013 Репутация: 3 Всего: 6 |
я бы первым делом избавился от synchronize
совсем (есть postmessage, events и можно общаться просто через переменные/поля) synchronize - главный источник проблем начинающих многопоточников |
|||
|
||||
UKRtortik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 29 Регистрация: 24.3.2014 Репутация: нет Всего: нет |
А как без синхронизации сделать, я не много не понял.
|
|||
|
||||
PointerToNil |
|
|||
![]() Профиль Группа: Участник Сообщений: 108 Регистрация: 17.6.2013 Репутация: 3 Всего: 6 |
я же ключевые слова давал
или хотя бы так: http://codeguide.ru/peredacha-informatsii-...oka-delphi.html (только postmessage вместо sendmessage) |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
С Synchronize запись в Memo делается двумя строчками кода. Извращаться для данной задачи с помощью PostMessage - это как в Питер из Москвы через Владивосток. Можно, но не целесообразно. При любом раскладе, даже с помощью PostMessage, мы передаем управление в VCL-поток для отрисовки Memo. Так почему же не воспользоваться специально предназначенным для этого Synchronize? Ну а общение через переменные - это вообще аут. А как эти переменные в VCL-потоке считывать? Цикл крутить? Таймер задействовать? Synchronize тут правильно использовано.
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
UKRtortik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 29 Регистрация: 24.3.2014 Репутация: нет Всего: нет |
ну так как мне правильно сделать? В чем у меня ошибка?
|
|||
|
||||
Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 26 Всего: 146 |
сначала надо определится в каком месте виснет
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. ![]() |
|||
|
||||
CynicRus |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 248 Регистрация: 31.5.2012 Репутация: нет Всего: 5 |
В 17-ой строке у тебя ошибка. А если серьёзно - загружаешь свой проект, и пошагово смотришь по нажатию F8, где же он тормозит. Предварительно расставив бряки.
Это сообщение отредактировал(а) CynicRus - 14.4.2014, 21:01 |
|||
|
||||
UKRtortik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 29 Регистрация: 24.3.2014 Репутация: нет Всего: нет |
а что не так в 17 строке?
|
|||
|
||||
CynicRus |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 248 Регистрация: 31.5.2012 Репутация: нет Всего: 5 |
Это древняя шутка про отсутствие телепатических способностей. К делу отношения не имеет. Просто посмотри под отладчиком. |
|||
|
||||
UKRtortik |
|
|||
Новичок Профиль Группа: Участник Сообщений: 29 Регистрация: 24.3.2014 Репутация: нет Всего: нет |
просто не очень понимаю как пользоватся отладчиком....
Добавлено через 1 минуту и 50 секунд
|
|||
|
||||
PointerToNil |
|
|||
![]() Профиль Группа: Участник Сообщений: 108 Регистрация: 17.6.2013 Репутация: 3 Всего: 6 |
UKRtortik, проверил свою ссылку - не работает, весь сайт накрылся - а вы что молчите?? вот, держите копию:
http://webcache.googleusercontent.com/sear...oka-delphi.html а для начала я бы тупо закомментировал строку с synchronize и посмотрел бы на быстродействие Рoseidon> С Synchronize запись в Memo делается двумя строчками кода. точно. на этом все и ловятся Рoseidon> При любом раскладе, даже с помощью PostMessage, мы передаем управление в VCL-поток для отрисовки Memo. НЕТ же! асинхронное сообщение передаёт данные, а не управление. как и переменные. передать управление из потока в поток вообще невозможно, хотя можно организовать видимость этого, тупо приостановив "вызывающий" поток до завершения действия в "вызываемом", что и делает synchronize Рoseidon> Ну а общение через переменные - это вообще аут. А как эти переменные в VCL-потоке считывать? Цикл крутить? не "аут", а банальное низкоуровневое решение вы наверное удивитесь, но окно принимает/обрабатывает сообщения тоже крутя цикл согласен, что подобный низкоуровневый код лучше куда-то заинкапсулировать, но раз борланд не справился... можно юзать OmniThreadLibrary или AsyncCalls еще Рoseidon> таймер использовать? проще sleep, хотя я бы предпочел CreateEvent и WaitForSingleObject так уж вышло, что "из коробки" synchronize оказался единственным удобным средством для передачи сообщений VCL-потоку но эта штука специфичная. гораздо полезнее во многих случаях был бы "Asynchronize" - то есть то же самое, но без приостановки потока (т. е. без удара по быстродействию) вот тут недавно чел пострадал от synchronize: http://forum.vingrad.ru/index.php?showtopi...t&p=2604306 Это сообщение отредактировал(а) PointerToNil - 14.4.2014, 22:15 |
|||
|
||||
Poseidon |
|
||||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Вот, изучай.
По твоему подобные решения лучше Synchronize? Может вообще тогда на ассамблере писать, чо уж там? -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||
|
|||||
PointerToNil |
|
|||
![]() Профиль Группа: Участник Сообщений: 108 Регистрация: 17.6.2013 Репутация: 3 Всего: 6 |
Poseidon> По твоему подобные решения лучше Synchronize?
возможно, лучшее решение - Asynchronize, но его пока нет (и мне не нужно, а то мог бы попробовать набросать) врожденный порок (для кого-то - фича) synchronize никуда не денется: он тупо останавливает вызывающий поток! кому это нужно? мне нет, поэтому любое решение, этого не делающее - для меня лучше Poseidon> Может вообще тогда на ассамблере писать, чо уж там? если речь о функции-утилите, которая пишется 1 раз, а используется в тысяче мест - то многие так и делают (в применении к потокам - смысла в ассемблере нет) Это сообщение отредактировал(а) PointerToNil - 14.4.2014, 23:08 |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Это дает гарантию, что к общему ресурсу (в частности к VCL-объекту) имеет доступ только один поток. Видимо PointerToNil не сталкивался с ситуациями, когда пока один поток перепрыгнет на одну строку, второй поток уже считает данные и изменит их. Synchronize для того и задуман, что бы гарантировать доступ только одного потока. Если у нас ситуация, когда один поток должен работать с данными, которые высчитываются в другом потоке, то как можно гарантировать правильность расчетов?
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
PointerToNil |
|
|||
![]() Профиль Группа: Участник Сообщений: 108 Регистрация: 17.6.2013 Репутация: 3 Всего: 6 |
Poseidon, у меня просто слов нет, чтобы выразить...
конечно, к VCL-объекту имеет доступ только один поток - поток VCL!!! не в вызывающем же потоке исполняется метод-параметр synchronize! если возникли сомнения: http://forum.vingrad.ru/index.php?showtopi...st&p=480368 и подробнее: http://www.delphiplus.org/articles/delphi/...s_programs.html вот только зачем вызывающий поток-то для этого останавливать? это даже гарантию немедленного исполнения требуемого действия не может дать - поток VCL чем-то своим еще может быть занят хотя на однопроцессорных и однотредовых машинах эта остановка еще имела смысл (ускорить запуск требуемого метода), но на многопроцессорных смысла уже не осталось очевидно, это - реликт, оставшийся от старой эпохи (хотя скорее всего могли и тогда более правильно это сделать) а вот и возможное решение (из второй ссылки): По сравнению с Delphi 7 в классы потоков Delphi 2009 внесено много изменений. Прежде всего, в класс TThread добавлена группа перегруженных методов Queue, которые позволяют синхронизировать вызов методов с главным потоком в неблокирующем режиме. Poseidon> Видимо PointerToNil не сталкивался с ситуациями, когда пока один поток перепрыгнет на одну строку, второй поток уже считает данные и изменит их конечно нет, как же это, совсем без критических секций что ли?? (а для простых типов данных, <=4 байта - есть interlocked* функции) Poseidon>Если у нас ситуация, когда один поток должен работать с данными, которые высчитываются в другом потоке, то как можно гарантировать правильность расчетов? ну как бы сразу напрашивается переменные/поля на 3 состояния, сигнализирующие о том, что обработка данной порции данных еще не начата/начата/уже закончена или 2 переменные - счетчики числа взятых на обработку элементов и числа уже обработанных (причем синхронизировать доступ к ним (interlocked*) нужно только для операции установки состояния "взято на обработку" или увеличения счетчика взятых на обработку, только между несколькими потоками-обработчиками и только в случае, если их несколько, а VCL-поток волен читать их в любой момент) - но для кого-то это может показаться слишком простым и низкоуровневым, [sarcasm] тут же без пары крутых специальных классов с дюжиной методов не обойтись [/sarcasm] не любите циклы с ожиданием? используйте CreateEvent, (Re)SetEvent и WaitFor(Single|Multiple)Object Это сообщение отредактировал(а) PointerToNil - 15.4.2014, 03:23 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "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. |