nesco, благодарю за подробные разъяснения и примеры! Это настоящий рождественский подарок для hiasm-щика. На мультипоточную схему, пусть и непроверенную, с удовольствием посмотрю.
Редактировалось 1 раз(а), последний 2019-01-07 12:11:51
Этот топик читают: Гость
Ответов: 704
Рейтинг: 7
|
|||
карма: 0 |
|
Разработчик
Ответов: 26113
Рейтинг: 2126
|
|||
Neo писал(а): На мультипоточную схему, пусть и непроверенную, с удовольствием посмотрю.MultiDownLoadURL_006 Но нужно обновить HTTP_Get, я там ввел возможность менять UserAgent-a в RealTime-e. Редактировалось 1 раз(а), последний 2019-01-07 13:37:34 |
|||
карма: 22 |
| ||
файлы: 1 | MultiDownLoadURL_006.zip [7.9KB] [523] |
Ответов: 704
Рейтинг: 7
|
|||
Оптимизирую "джунгли" по новым "понятиям" о потоках. Стало уже стабильнее. Но разбираясь с примером выше, обнаружил что идет работа вообще без мьютексов. И обратился к штатному примеру, вспомнить как его вообще применять. Так получается что выводить в оконные элементы можно из параллельного потока прямо по onExec? Да и читать данные из того же Text тоже можно в параллельном потоке? Считал что обращаться к оконным элементам из параллельного вообще нельзя, только через синхронизированные с главным потоком события. Может есть что почитать на эту тему применимо к HiAsm?
Штатную схему прикрепляю.
|
|||
карма: 0 |
|
Разработчик
Ответов: 26113
Рейтинг: 2126
|
|||
Neo писал(а): Так получается что выводить в оконные элементы можно из параллельного потока прямо по onExec?Можно, но не нужно. Работает это крайне нестабильно. Neo писал(а): Да и читать данные из того же Text тоже можно в параллельном потоке?Это можно, команды на перерисовку контрола, в таком случае, не возникает. Neo писал(а): Но разбираясь с примером выше, обнаружил что идет работа вообще без мьютексовЕсли в моем примере, то там их отродясь и не было за ненадобностью, как, кстати, и вот этого там тоже нет Neo писал(а): получается что выводить в оконные элементы можно из параллельного потока прямо по onExec?Neo писал(а): Штатную схему прикрепляюХа, тебя сбивает с толку управление из потока напрямую контролами, но так это просто пример. В основных, стабильных схемах так лучше не делать. Редактировалось 4 раз(а), последний 2019-01-08 03:13:27 |
|||
карма: 22 |
|
Ответов: 704
Рейтинг: 7
|
|||
nesco, благодарю! Супер-понятно и подробно.
|
|||
карма: 0 |
|
Ответов: 4628
Рейтинг: 749
|
|||
nesco писал(а): внутренним методом Sender.Synchronize(SyncExec), а сам продолжает выполняться дальше ... те параллельный поток не ждет окончания события главного потокаРедактировалось 1 раз(а), последний 2019-01-08 13:19:03 |
|||
карма: 26 |
|
Разработчик
Ответов: 26113
Рейтинг: 2126
|
|||
Netspirit писал(а): А он использует SendMessage()Елки, а ведь точно. Тогда поток повиснет на время работы обработчика главным потоком. Вот почему поток работает с интерфейсным и элементами. Какие у тебя по этому вопросу мысли? Редактировалось 1 раз(а), последний 2019-01-08 17:09:34 |
|||
карма: 22 |
|
Ответов: 4628
Рейтинг: 749
|
|||
nesco писал(а): Какие у тебя по этому вопросу мысли?Редактировалось 4 раз(а), последний 2019-01-08 15:03:53 |
|||
карма: 26 |
|
Разработчик
Ответов: 26113
Рейтинг: 2126
|
|||
Получается так, что onSyncExec и Synchronize вызывают обработчик главного потока и ждут завершения его работы. Но на время обработки сообщений главным потоком параллельный поток останавливается и ничего не может делать параллельно. Вот мне тут не понятен один момент -- а что, если интерфейсный элемент задержится с обработкой сообщений, а лимит времени остановки параллельного потока закончится? Или этот лимит бесконечен? Ты по этому вопросу, случаем, ничего не знаешь?
|
|||
карма: 22 |
|
Ответов: 16884
Рейтинг: 1239
|
|||
Видит бог - долго терпел.
Neo писал(а): Столкнулся с тем, что таблица строк на 7 строк по 38 колонок каждая ощутимо тормозит главный поток при полной перерисовке через замену строк. Оказывается вроде нет. Neo писал(а): Просто каждые 3 секунды данные в таблице полностью обновляются и к таблице имеют доступ через матрицу строк или массив строк другие участки схемы Neo, вопросы: 1. Зачем другим участкам схемы визуальная таблица строк? 2. Кому нужна 3-х секундная моргалка на экране? Редактировалось 2 раз(а), последний 2019-01-08 21:14:43 |
|||
карма: 25 |
|
Ответов: 704
Рейтинг: 7
|
|||
Tad, создавал программу давно когда еще трава была зеленее. Сейчас перестраиваю все под новый контроллер и под новые принципы. Таблица осталась изначально как отображение текущего положения дел. Иногда нужно ее посмотреть. Хотя сейчас планирую данные переносить в невизуальную матрицу строк и массив строк - так ведь надежнее? Но в таблице так удобно было с ними работать и наблюдать. Придется периодически перечитывать массив в таблицу для наблюдения. А вот сама таблица почему-то долго перерисовывается на некоторых вин10, пока не понял в чем дело.
|
|||
карма: 0 |
|
Ответов: 16884
Рейтинг: 1239
|
|||
Neo, вин10 32,64 ? Памяти сколько ?
|
|||
карма: 25 |
|
Ответов: 704
Рейтинг: 7
|
|||
Х64, памяти 8ГБ. По удаленке единственное, проверяю. Но на моем ноуте тоже х64 есть мелкие подвисания главного потока из-за талицы. В Вашем примере стабильно 10 событий/сек, а у меня та же схема 8-12 плавает если ее двигать активно. При этом ВинXPх86 с 2ГБ памяти даже намека на подвисания не дает и по удаленке. Пробовал на 10 отключать эффекты визуальные - ничего не меняет.
Редактировалось 4 раз(а), последний 2019-01-09 00:57:36 |
|||
карма: 0 |
|
Разработчик
Ответов: 26113
Рейтинг: 2126
|
|||
Neo писал(а): Пробовал на 10 отключать эффекты визуальные - ничего не меняет.Попробуй для проверки принудительно включить высокий приоритет графики для своего приложения -- Win+I -> Игры -> Игровой режим -> Настройки Графики. У меня и для HiAsm включен этот режим. Редактировалось 2 раз(а), последний 2019-01-09 02:43:17 |
|||
карма: 22 |
|
Ответов: 4628
Рейтинг: 749
|
|||
nesco писал(а): а что, если интерфейсный элемент задержится с обработкой сообщений, а лимит времени остановки параллельного потока закончится?Для посылки сообщения с таймаутом ожидания есть функция SendMessageTimeout(). Но этот вопрос не является каким-то особо принципиальным. Всё укладывается в принципы совместного доступа к какому-либо ресурсу ("синхронизации"): все конкурирующие потоки при доступе к общему ресурсу стают в ожидание (различными методами) освобождения ресурса, после чего по очереди получают эксклюзивный доступ. А задача программиста - правильно определить такие совместно используемые данные, обезопасить их, минимизируя "узкие места". По поводу последней схемы от Neo: всё же доступ к Edit, LED и прочим визуальным компонентам из параллельных потоков, как и говорил nesco, плохая идея. В целом ты вроде правильно используешь SafeMode, но, во-первых, "общими данными" для 2-х параллельных потоков является точка For.Position - первый SafeMode можно поставить только на запись этой точки, а второй - на чтение: чем меньше времени один поток занимает ресурс, тем меньше времени остальные потоки его ждут, тем больше полезных действий они выполнят параллельно. Во-вторых, работая с визуальными компонентами из параллельных потоков через SafeMode ты забываешь, что кроме твоих 2 явных потоков есть ещё и третий конкурирующий поток, обращающийся к тем же визуальным компонентам - главный поток приложения, обрабатывающий сообщения компонентам от системы. Это и является упомянутой выше проблемой доступа к визуальным компонентам из параллельных потоков. В некоторых случаях будет работать, а в некоторых будет давать ошибку. И SafeMode здесь не очень поможет - нужно использовать Synchronize, чтобы заставить ждать главный поток, пока параллельный поток работает с визуальным компонентом (на самом деле, "ждёт" параллельный поток, пока главный занимается исключительно его задачей, не отвлекаясь на другие сообщения). Небольшое рассуждение по поводу Application.doProcessMessages из параллельного потока. Механизм оконных сообщений Windows реализован таким образом.
Оконные сообщения обрабатываются некоторым потоком некоторого процесса. Следовательно, у этого потока есть некоторая очередь сообщений, куда система их складывает в порядке поступления. А как система знает какой поток какого процесса должен обработать сообщение данного окна? Ответ: тот поток, который и создал данное окно. Когда приложение однопоточное, при старте система создаёт один поток ("главный поток"). Этот поток создаёт все необходимые окна (например, главную форму приложения и тулбар с кнопками в ней). Затем входит в цикл выборки сообщений из своей очереди, а следовательно, только для созданных им самим окон. Например, от тулбара приходит сообщение клика на кнопку с индексом кнопки - главный поток ищет обработчик onClick данной кнопки, по которому, например, можно открыть другое окно. И хоть это другое окно "независимо" от главного (между ними можно переключаться, перемещать и т.д.), но тем не менее оно всё равно было создано главным потоком и его сообщения приходят и обрабатываются главным потоком. Что делает doProcessMessages - он просто принудительно делает выборку и обработку всех накопившихся сообщений теми же функциями, которыми это делает главный поток в цикле обработки сообщений. Вот только если делать doProcessMessages из главного потока, то сообщения будут обработаны, поскольку главный поток создавал окна и для него есть сообщения. А параллельный поток никаких окон не создавал и ему нечего обрабатывать. Собственно, задача doProcessMessages - например, принудительно перерисовать окно во время обработки какого-то пользовательского сообщения типа onClick: для перерисовки всех окон им надо послать сообщение WM_PAINT, но эти сообщения не будут обработаны пока мы не завершим обработку нашего клика. А нам уже срочно нужно показать пользователю, что по его клику что-то происходит в программе. В связи с выше изложенным можно провести любопытный эксперимент. Может кто замечал: если обычный Timer включить из параллельного потока, то события onTimer не будет - таймер реализован через сообщения, сообщения приходят создавшему ("включившему") его потоку, но поток не обрабатывает этих сообщений (или вообще сразу завершается). Но если после включения таймера в этом же потоке начать в цикле вызывать Application.doProcessMessages, то события у таймера начнут происходить (в этом же параллельном потоке). Наводящий вопрос: а можно ли "нормально" включить таймер из параллельного потока? Ответ - можно, "передав задачу" его включения главному потоку с помощью компонента Synchronize (или по Thread.onSyncExec). Редактировалось 18 раз(а), последний 2019-01-09 13:29:00 |
|||
карма: 26 |
| ||
Голосовали: | nesco |