1nd1g0, посмотрите, пожалуйста, в мою схемку. Там я вставил проверку на завершенность потока банально через Hub, который запрещает/разрешает следующее событие. Верно получается?
------------ Дoбавленo в 20.25:
Я его тестировал на слипе секундном - работало вроде. Но слип это слип...
Этот топик читают: Гость
Ответов: 704
Рейтинг: 7
|
|||
карма: 0 |
|
Ответов: 3889
Рейтинг: 362
|
|||
Neo писал(а): в мою схемкуТак я сперва и посмотрел Neo писал(а): проверку на завершенность потока банально через HubПардон, может речь о SafeMode ![]() |
|||
карма: 1 |
|
Ответов: 704
Рейтинг: 7
|
|||
Что-то мне кажется я снова влепил этот SafeMode наобум еще и с Wait... конечно оно там все копится и получается большой бумс
![]() |
|||
карма: 0 |
|
Ответов: 3889
Рейтинг: 362
|
|||
Neo, я Вас почти запутал, но посмотрел в исходники Thread, там стоит системный Sleep, так что паника отменяется, поток на Wait действительно подвисает, но отдаёт управление другим потокам. В этом его кардинальное отличие от Sleep HiAsm. А вот MMTimer действительно натворил бы дел на его месте, наплодив потоков.
|
|||
карма: 1 |
|
Ответов: 704
Рейтинг: 7
|
|||
Эээ... То есть можно убрать оттуда SafeMode и это должно решить проблему? Зачем мне чтоб оно подвисало там, если поток не пройдет на исполнение в случае незавершенности предыдущего? Стоит же If_else для отслеживания этого
![]() ------------ Дoбавленo в 21.00: Из стека же за 15 миллисекунд успеет вытянуть строчку, а потом ставится блокировочка на пропуск следующего события из Thread. ------------ Дoбавленo в 21.02: Хотя и так ему не должно быть жарко - пусть себе выполняется новое событие даже до окончания первого - там же проверка If_else его выкинет в никуда ------------ Дoбавленo в 21.02: Или я что-то не то горожу? |
|||
карма: 0 |
|
Ответов: 3889
Рейтинг: 362
|
|||
Neo писал(а): Зачем мне чтоб оно подвисало там, если поток не пройдет на исполнение в случае незавершенности предыдущего? Стоит же If_else для отслеживания этогоSafeMode Вам нужно вешать на любые обращения к этому стеку извне, чтобы блокировать одновременные doPush и doPop из параллельных потоков (не забываем про основной поток приложения). А сама логика итераций Thread не даст начаться новой, пока не завершился старая, я выше это описал. И на 15 мс ваш Thread отдаёт управление другим потокампроцессам, потом снова забирает на себя. Если ядро у процессора одно и не очень быстрое, и каждые 15 мс по onEvent1 выполняется достаточно ресурсоёмкая задача, то загрузка действительно может стать заметной. |
|||
карма: 1 |
| ||
Голосовали: | Neo |
Ответов: 704
Рейтинг: 7
|
|||
А если ситуевина такая: один такой поток выдает события на проигрывание синхронизированного массива звуков, второй - строковую несложную задачу, третий аналогичное. И все они с интервалом в 15. То получается все они начинают через 15 миллисекунд одновременно терзать процессор, отнимая все на себя? Если запустить каждый поток с одним интервалом итераций, но в разное время по таймеру (например один через 100 миллисекнуд, другой через 150, третий через 200) - получится решить проблему?
Раз со стеком работаю разные потоки (на запись и на чтение разные), то на запись SafeMode =Wait, а на чтение SafeMode =NoWait - верно? И о том, что Thread не даст начаться новой, пока не завершился старая - он же будет копить все эти итерации пока не обработает, и создавать этим огромную очередь? Я разве не решаю эту проблему использованием того If_else? Мне просто хотелось чтоб стек читался как можно чаще, и в новом потоке, не задерживая основную задачу - вот и поставил 15 миллисекунд, но с выключателем через If_else: вышли данные из стека - включилась отсечка на новые итерации потока. Завершился поток - снова разрешается читать стек. Вообще чего связался с этими потоками: основная задача - читать и писать в com-порт. Но большинство принимаемых данных не представляют ценности, а бывает, что приходят нужные данные. Но их обработка не является сверхсрочной и можно продолжать читать порт дальше. Так вот данные заходят в стек и порт читается дальше себе. А новый поток опрашивает стек и обрабатывает очередь, записывая результат в память. Таким образом поддерживается нужная скорость опроса порта, и обработка данных идет в фоновом режиме (по крайней мере так планирую ![]() |
|||
карма: 0 |
|
Ответов: 3889
Рейтинг: 362
|
|||
Neo писал(а): через 15 миллисекунд одновременно терзать процессор, отнимая все на себя?Вы бы поискали совсем недавнее наше обсуждение подобной темы с Login, там я как раз давал пример запуска таймеров со смещением, но там нужна была некоторая точность, потому там именно таймеры. В Вашем случае не стоит путать потоки и ММ-таймеры (обычные таймеры вообще не наш случай, они не порождают отдельный поток и не так точны). Зарегистрированное на таймер событие (onTimer), действительно вызывается системой каждые, скажем, 15 мс, порождая новый поток. Если процессор одноядерный, то физически остальные потоки на этот момент прерываются. Ваш же случай использует Thread, который не вызывается каждые 15 мс, а засыпает на 15 мс после выполнения каких-то задач. Это кардинальная разница. Например, если задача занимает целую секунду, то график работы будет 1сек_работы - 15мс_сна - 1сек_работы - 15мс_сна. Если потоков у Вас, скажем, два, и второй тоже выполняет что-то, требующее секунду на обработку, а процессор одноядерный либо многоядерный, но всё распределилось на одно ядро, то никто ему после 15мс сна управление не вернул бы и график должен был бы выглядеть так: 1_поток_1сек_работы - 2_поток_1сек_работы - 1_поток_1сек_работы. То есть Delay указывает минимум сна, максимум же теоретически не ограничен и определён работой соседних потоков. Однако на практике всё несколько сложнее, помимо встроенной в Thread задержки, система самостоятельно усыпляет потоки с определёнными интервалами, зависящими от их приоритета исполнения, загруженности ядер и т.п. и отдаёт управление другим. Эти интервалы могут быть не кратны ни Delay потока, ни времени исполнения обрабатываемой им итерации. При этом не забываем, что ещё и основной поток приложения хочет работать и ему тоже выделяется время, на которое все остальные усыпляются (опять же, если не работают в отдельном ядре процессора). Это я Вам ещё про прерывания решил не рассказывать ![]() Как видите, задержка (Delay) - вещь условная, и на практике не должна быть основой для точных иили синхронизированных по времени задач. И должно быть понятно, для чего сделан SafeMode - регулярно прерывая потоки, система передаёт управление другим, и не дай бог это какое-нибудь чтение из стека, в который, например, наполовину не дописались данные из параллельного потока, а система приостановила запись и отдала управление потоку чтения. Neo писал(а): данные заходят в стек и порт читается дальше себе. А новый поток опрашивает стек и обрабатывает очередь, записывая результат в память.![]() |
|||
карма: 1 |
|
Ответов: 704
Рейтинг: 7
|
|||
1nd1g0 писал(а): система передаёт управление другим, и не дай бог это какое-нибудь чтение из стека, в который, например, наполовину не дописались данные из параллельного потока, а система приостановила запись и отдала управление потоку чтенияПолучил для себя "открытие Америки" ![]() Для меня казалось что оно все выполняется и выполняется себе по веточкам. А выходит (если я уловил) что все параллельные потоки, которые в программе, прерываются по-очереди чтоб не получалось застойных потоков? И тогда я не пойму как мне расставить SafeMode возле стека, чтоб убить ошибку Access Violation at address... (поскольку с применением SafeMode Wait на запись в стек она снова вернулась) и не получать 100% загрузку одноядерного процессора. Не ставлю SafeMode - получается загрузка под 100, ставлю - получаю стабильно Access Violation at address... ![]() При этом всем у меня получается все в параллельных потоках: его создает асинхронный com-порт - передает в 3 разных стека; из трех стеков запускается обработка в новых потоках; из 2 из этих новых потоков запускается еще одна обработка в новых потоках (после работы с БД, которая убивает новый поток). Получается, что изначально из-за com-порта, который плюется потоками, вся основная программа почти не выполняется в системном потоке. Отсюда и такая ерунда с отладкой ![]() Стек гарантированно наполняется медленнее, чем считываются данные из него. Например наполнение раз в 2 секунды 1 значением, а считывание с обработкой занимают не больше секунды. Хотя бывает что за раз приходит в стек 6 строк, но гарантированно затишье на минуту+. ------------ Дoбавленo в 13.59: Еще добавлю, что есть стек, в который пишется и читается из разных потоков. И каждое дейтвие на запись должно быть обязательно выполнено, как и действие на чтение. Посему на запись и на чтение я поставил по SafeMode Wait - я сделал глупость или нет? |
|||
карма: 0 |
|
Ответов: 3889
Рейтинг: 362
|
|||
Neo писал(а): я поставил по SafeMode Wait - я сделал глупость или нет?Надо понимать, что эти потоки подвиснут, пока стек кем-то занят, но, если занявший не подвис сам, в конце концов отработают. А вот Neo писал(а): Access Violation at address |
|||
карма: 1 |
|
Ответов: 1429
Рейтинг: 50
|
|||
Neo, а вы тоже музыкальный секвенсер пишите как и я?
|
|||
карма: 0 |
|
Ответов: 704
Рейтинг: 7
|
|||
login, нет
![]() ![]() ------------ Дoбавленo в 16.00: 1nd1g0, спасибо за предложение! Сейчас "разожму" ее и буду ждать ошибку. А вот убрать все сторонние - там у меня сторонник com порт, но без него никак - он один пашет нормально. И есть стек сторонний, но он тоже уникален возможностью FIFO. ![]() |
|||
карма: 0 |
|
Ответов: 3889
Рейтинг: 362
|
|||
Neo писал(а): А вот убрать все сторонние - там у меня сторонник com порт, но без него никак - он один пашет нормально. И есть стек сторонний, но он тоже уникален возможностью FIFOЯ имел в виду, убрать всё то, что замедлит и усложнит диагностику кому-то кроме Вас по причине отсутствия компонент и лишнего свободного времени. То, что можно, заменяйте эмуляторами, например, генераторами чисел и т.п. Так больше людей смогут Вам помочь. |
|||
карма: 1 |
|
Ответов: 704
Рейтинг: 7
|
|||
1nd1g0, спасибо, учту.
------------ Дoбавленo в 22.19: Сижу жду с моря погоды. Уже раз загрузилось до 100 и слетело. Access Violation at address... пока не наблюдается. Вывод - обладает зачатками интеллекта и боится быть излеченным ![]() |
|||
карма: 0 |
|
Ответов: 704
Рейтинг: 7
|
|||
1nd1g0, я ее выждал! http://forum.hiasm.com/forum_serv.php?q=56&id=2694 - вот она, коварная! Помогите, пожалуйста!
|
|||
карма: 0 |
|