Отправлено: 14.05.18 21:33. Заголовок: Вылет из программы...
Всем привет ! Как можно в МиниГуи программе сделать вызов своих функций при аварийном завершении программы (т.е. при вылете) ? Т.е. хочу сделать сразу после появления MsgBox() вызов 2-3 функций и потом сделать DbCloseAll(). Как это реализовать ?
Для чего это нужно, поясню: при входе в свою программу я пишу в базу кто и когда вошел в программу (логин пользователя). И при выходе из программы, стираю этого пользователя из базы. Если программа "вылетает", то юзер числится как работающий. Древнее наследие с клипера, хотел переделать, да так и осталось.
FUNCTION myThr_File(cFile, hWnd, nMsg, nSek) LOCAL lFile, cRun, cPar, lPost := .T. LOCAL cFileExe := "xxx.exe" // прога на C# LOCAL cFileTerm := "xxx4.exe" // прога на терминалке
Этот код не должен валить tsbrowse, но есть нюансы 1. Поток никогда не завершится в такой реализации . после первого убиения процессов, файл семафора xxx.stop . будет игнорироваться 2. Поток не указан как join или detach что не есть хорошо 3. myThr_Stop() если где-то вызывается это не остановка потока, а отсоединение от основного процесса, далее см п. 1 4. Какой смысл в потоке после убиения двух процессов? Поток будет молотить бесконечно вызывая каждые 2 секунды пару doevents() и игнорить семафор там где надо и не надо. и опять см п. 1 5.Ну и без мютекса вывод в лог через ? .... Может вызвать конфликт с попыткой вывода из основного процесса
Возможно все это и может спровоцировать ошибку. Что лучше сделать в этом примере 1. при создании потока сразу его отсоединить детачем 2. цикл while . t. заменить на while lPost Тогда event:0 запустится поток, дождется семафора, убъет указанные процессы и завершит работу освободив ресурсы 3.Вывод в лог через ? ... лучше делать через мютекс
4. Какой смысл в потоке после убиения двух процессов?
Немного уточнение к коду. При появлении файла семафора xxx.stop - убиваются 2 процесса и прога потом завершается. При завершении проги уже все ресурсы освободятся. Не понял пункты 1 и 3 ? Можно ли более подробно написать ?
Отправлено: 22.05.26 18:04. Заголовок: Andrey пишет: Не по..
Andrey пишет:
цитата:
Не понял пункты 1 и 3 ?
1 цикл потока вечный , нет условия завершения потока даже после обнаружения семафора. . при этом поток нии свободный ни присоединённый 3 детач не завершает поток
Хотя бы deepseek сприси Если поток в Harbour не отсоединён (hb_threadDetach) и к нему не присоединились с помощью hb_threadJoin, это может привести к утечке системных ресурсов и создать так называемый «zombie-поток».
Обычно эта проблема выглядит как постепенная утечка памяти и дескрипторов, которая может замедлить систему или привести к аварийному завершению программы при большом количестве таких потоков. Это не приводит к мгновенному сбою, но последствия для долго работающих приложений могут быть серьёзными:
· Утечка критических ресурсов: Harbour создаёт «присоединяемый» поток. Когда он завершается, его стек освобождается, но жизненно важные структуры (идентификатор потока, код возврата и т.д.) остаются в памяти до вызова hb_threadJoin или hb_threadDetach. · Невозможно создать новый поток: При исчерпании системных лимитов могут возникать ошибки вроде EAGAIN при создании нового потока, а также ошибки создания мьютексов или других объектов ядра. · Риск зависания приложений: Постоянное потребление ресурсов без освобождения со временем приводит к нестабильной работе или аварийному завершению программы.
Чтобы этого избежать, достаточно придерживаться простого правила: для каждого созданного потока нужно либо вызвать hb_threadDetach, если результат не нужен, либо hb_threadJoin, когда важно дождаться его выполнения и освободить ресурсы. Некоторые разработчики ошибочно полагают, что достаточно просто «забыть» о потоке, но это прямой путь к проблемам. Как лучше поступить в вашей конкретной ситуации — сразу отсоединить поток, если его результат не нужен, или корректно присоединить его?
Если 1 и 3 относятся к рекомендациям, то в документации Александра , есть и описание и примеры работы с детачем и мютексами. Все в разделе многопоточность Если коротко, то поток не может быть ничей ни detach ни , join А мутексы это семафорчики для потока обозначающие блокировку работы с разделяемыми ресурсами. Вывод в лог это разделяемый ресурс файл
Отправлено: 22.05.26 19:00. Заголовок: Есть пример у Григор..
Есть пример у Григория C:\MiniGUI\SAMPLES\Advanced\Tsb_2WndType который я сделал благодаря Сергею, вот там и реализована подобная схема, может и неправильно сделал, но работает. Очень хочется видеть ПРАВИЛЬНОЕ использование потоков в МиниГуи, чтобы и другие могли это использовать. Большая просьба к Haz поправить этот пример.
Дим, потоки в GUI и CONSOLE ведут себя по разному В GUI более жёсткие требования, и то что пролетает со свистом в консоли может встать колом гуи Вообще этике предполагает потоки либо джойнить либо детачить Пример код Андрея выше, там нет ничего явного что можно связать с tsbrowse и потоком, но вылет есть. Более того , язык медленно, но развивается, могут ужесточить проверки и оптимизировать код и тогда все что работало годами валиться без предупреждения Это тоже из личного опыта говорю. Хуже нет разбираться со своим старым кодом . проще заново написать.
Отправлено: 22.05.26 20:37. Заголовок: Haz пишет потоки либ..
Haz пишет
цитата:
потоки либо джойнить либо детачить
У Андрея, должен быть hb_threadDetach(), в примере он есть. При входе в окно (ON INIT ... :Event( 0... thread создается, в ON RELEASE ... это :Event(90,... делается myThr_Stop(ow:Cargo:hThr), т.е. hb_threadDetach( hThr ) перед другими командами). При срабатывании потока на файл, в событии nMsg работа окна завершается. По мне thread не причем, тсб валится по др. причинам. Лог, конечно надо вести через мютекс или общую переменную, например (пример был) PUBLIC o_Thr ; o_Thr := TThrData():New() // создадим контейнер для работы с потоками // create a container for working with streams но видно не зашло
Отправлено: 22.05.26 21:05. Заголовок: SergKis пишет: У Ан..
SergKis пишет:
цитата:
У Андрея, должен быть hb_threadDetach
Может быть, но код не представлен SergKis пишет:
цитата:
ON RELEASE ... это :Event(90,... делается myThr_Stop(ow:Cargo:hThr), т.е. hb_threadDetach( hThr ) перед другими командами
Сергей , а какой смысл в детаче потока после выполнения задачи? Так он после окна также останется молотить в холостую пока программа не завершится
Детач этого потока нужно делать сразу после открытия hb_threadDetach((hb_threadStart()), а после выполнения задачи потока(поймали ххх. stop) прерывать цикл. завершая поток И более того даже поток здесь нужен другой, не постоянно крутящийся, а запускающийся по событию сторожа изменения целевого каталога. Тогда поток стартанет проверит появился ли ххх. stop и завершится. Паша давно кидал код сторожа.
что касается причин ошибки, из куска кода tab не при делах, но все же порядок навести надо. И есть сомнения , что errorsys вообще правильно в могопоточке словит ошибку. К примеру в потоке деление на ноль, а программа живёт и что поток сдох никак не узнать. Каких только чудес не насмотрелся пока вендинговый аппарат приучал к картам emmarine.
Отправлено: 22.05.26 21:31. Заголовок: Haz пишет какой смыс..
Haz пишет
цитата:
какой смысл в детаче потока после выполнения задачи?
Это к Андрею - его мысли. Для задачи Андрея (определять файл), поток не нужен, совсем. А на окне, пока оно существует, существует и поток, вполне нормальный вариант (отрабатывать запросы окна, например)
цитата:
Каких только чудес не насмотрелся
Если вспоминать историю работы потоков, начиная с clipper, когда надо было переписывать код потока (правила менялись), выкинул их из употребления. Надо поток, запускаю в фоне прогу и общайся с ней как надо, убирай, когда не надо и ... голова не болит, общие правила. Это к правилам потоков
цитата:
И есть сомнения , что errorsys вообще правильно в могопоточке словит ошибку. К примеру в потоке деление на ноль, а программа живёт и что поток сдох никак не узнать
Детач этого потока нужно делать сразу после открытия hb_threadDetach((hb_threadStart()), а после выполнения задачи потока(поймали ххх. stop) прерывать цикл. завершая поток И более того даже поток здесь нужен другой, не постоянно крутящийся, а запускающийся по событию сторожа изменения целевого каталога. Тогда поток стартанет проверит появился ли ххх. stop и завершится. Паша давно кидал код сторожа.
Есть готовый пример у Григория C:\MiniGUI\SAMPLES\Advanced\Tsb_2WndType Там есть кнопка Stop - это для админа, нажимаем и прога завершается, т.е. тестировка режима завершения программы у всех юзеров работающих с программой. Сделано специально в отдельном потоке, для показа работы в МиниГуи с потоками, примеров в библиотеке очень мало. Вопрос ко всем - как правильно реализовать такой режим, чтобы потом это можно добавлять в свои проекты ?
Отправлено: Вчера 11:10. Заголовок: Перешёл на новую вер..
Перешёл на новую версию 26.05 Pro Один юзер в программе, других открытых программ нет. Что-то стал падать рабочий код, раньше такого не было. Ошибка по GETWINDOWRECT примерно так:
Time from start: 0 days 0 hours 1 mins 34 secs Error BASE/3012 Failed to get window rect: GETWINDOWRECT Args: [1] = N 0 [2] = N 3 --------------------------------- Stack Trace --------------------------------- Called from GETWINDOWRECT(0) Called from (b)TCONTROL(0) Called from TSBROWSE:NWIDTH(0) Called from TSBROWSE:DRAWLINE(0) Called from TSBROWSE:GOTOP(0) Called from TSBROWSE:RESET(0) Called from MAINCARDTABLE(4173) in module: Source\Tbrw_table.prg Called from MYACTIONENTER(1933) in module: Source\Tbrw_table.prg Called from (b)FORM_MYTABLE(853) in module: Source\Tbrw_table.prg Called from DO_WINDOWEVENTPROCEDURE(0) Called from TWNDDATA:DOEVENT(0) Called from DO_ONWNDLAUNCH(0)
Т.е. нахожусть в ТСБ, открываю карточку по одной записи, потом закрываю карточку и делаю по ТСБ oBrw:Reset(), далее вылет. Почему ? Может нужно как то переключиться заново на ТСБ ?
Все даты в формате GMT
3 час. Хитов сегодня: 128
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет