|
|
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
Бармолей _БалтикаПри таком подходе экономичнее будет пару макросов написать Каких? На самом деле их три должно быть 1. С определениями 2-х функций: а) функции потока регистрации потоков, поддерживающих протокол (кстати, не проще-ли сделать, чтобы сами потоки посылали сообщения, например установкой некоторого события) и б) функции завершения. 2. Запуска потока (а) 3. Вызова функции (б) далее Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2005, 12:46 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
В этот же хедер можно и протокол для dll-ов забить, написав свою функцию запуска потоков. Ну, примерно так Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2005, 13:22 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
Можно и так, но: 1) Поток может завершиться штатно и до завершения процесса, и тогда наши пританцовки в конце процесса для него не нужны. Надо будет исключать его из списка - еще один макрос, но уже в каждой реализации потока. 2) Очень жесткое требование, чтобы в большой программе всякое создание потоков проходило только через определенный макрос. А если мы будем это ловить в уже предоставленной системой функции DllMain, такое требование снимается. Кроме того, с использованием DLL экзешник лаконичнее Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. От писателя экзешника требуется только не забыть включить одну строчку [***]. Других ошибок ему не дадут сделать компилятор и линкер. С другой стороны, писатели потоков вообще не будут должны что-то делать. Но, когда они осознают, что могут много чего потерять при завершении процесса, и ужаснутся, им скажут - положись на ThreadMngr, и ты в 2 шагах от успеха :): 1) Поддержи у себя обработку 1 идентификационного сообщения. Дело не хитрое. Пришлют тебе ивент, а ты его и выстави. Вот тут можно и макрос предусмотреть. 2) А еще поддержи WM_QUIT. Завершайся по нему штатно. Это уж совсем просто будет, обычным образом написанный цикл обработки сообщений всегда завершится по WM_QUIT. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2005, 15:54 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
1) Описатели потоков в менеджере можно заносить в массив hThreadArray и ожидать их WaitForMultipleObject, и, дождавшись, исключать из hThreadArray 2) рекомендуют же разработчики vcишной библиотеки использовать вместо апишной CreateThreade - _beginthreadex из-за заморочек в других библиотеках. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2005, 16:11 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
это да ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2005, 16:44 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
БармолейБиблиотеки, использующие мою, о корректном завершении заботиться не должны - все перекладываем на экзешник. Для этого замутить отдельную DLL. .... Вот на такой подход я точно буду ругаться :) Одно дело знать что используемая библиотека требует явного старта и финиша (те самые DLL_Init() и DLL_Shutdown()) и совсем другое дело подключать какую-то еще dll причем надо будет следить чтобы она стартовала ДО рабочей dll и финишировала ПОСЛЕ нее. Получаем в итоге ту же самую проблему от которой пытались уйти только в еще более неудобном для решения виде. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2005, 17:47 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
Я конечно не супергуру и может что-то проскользнуло мимо меня, но какого извините меня не воспользоваться: DllMain: DLL_THREAD_ATTACH DLL_THREAD_DETACH Атачте библиотеку статически и следите за потоками на здоровье. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2005, 14:56 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
saintЯ конечно не супергуру и может что-то проскользнуло мимо меня, но какого извините меня не воспользоваться: Потому что DllMain вызывается системой ПОСЛЕ того как система сама вычистила все принадлежащие процессу треды. Плюс к этому DLL_PROCESS_DETACH может срабатывать в другом треде чем тот в котором работал DLL_PROCESS_ATTACH. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2005, 17:55 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
Привет, всех с праздниками! :) Видимо собака была зарыта в том, что без стакана с этими трэдами не разберешься, а вот теперя вроде стало яснее :). Есть наверное разные варианты, но можно вот что сделать. Почти то, что предложил saint с использованием DllMain, только которое под нашим собственным контролем (т.к. увы DllMain вызывается когда уже потоки прерваны, и причем DLL_THREAD_DETACH вообще не вызывается если завершение нештатное). И одновременно это почти то, что говорил White Owl, но только не придется выстраивать DLL в непростые последовательности зависящих друг от друга. Вобщем, делается DLL (у меня она ThreadMngr), из которой торчит наружу такой API Код: plaintext 1. 2. Те потоки в разных DLL нашего большого проекта, которые хотят добиться того, чтобы непременно завершаться штатно, должны подлинковать эту специализированную DLL-синхронизатор. Когда они начинают свою работу, они регистрируются с помощью ThreadMngr_RegisterThread(..., TRUE). Тут заодно передаем dwThreadId, который иначе, по одному только hThread из другого потока достать затруднительно. При штатном завершении поток вызывает ThreadMngr_RegisterThread(..., FALSE). Или можно на две отдельных функции разбить, не важно. Ну а экзешник таки перед финальным ретурном вызывает ThreadMngr_WaitThreads(). И в нем что-то типа Код: plaintext 1. 2. White Owl Бармолей Библиотеки, использующие мою, о корректном завершении заботиться не должны - все перекладываем на экзешник. Для этого замутить отдельную DLL. Вот на такой подход я точно буду ругаться :) Одно дело знать что используемая библиотека требует явного старта и финиша (те самые DLL_Init() и DLL_Shutdown()) и совсем другое дело подключать какую-то еще dll причем надо будет следить чтобы она стартовала ДО рабочей dll и финишировала ПОСЛЕ нее. Получаем в итоге ту же самую проблему от которой пытались уйти только в еще более неудобном для решения виде. Может я выразился в прошлый раз не так. В итоге получается, что о всех этих делах заботятся 2 стороны: 1) сам тот поток, который не хочет быть прерван "на полуслове" 2) экзешник, который "всему голова" :) А разные "третьи" возможные участники, ну то есть еще другие DLL, которые используют ту, которая генерит потоки, вот они уже не заботятся о вопросах корректного завершения тех потоков. Вроде так нормальненько :)). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2006, 16:03 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
БармолейМожет я выразился в прошлый раз не так. В итоге получается, что о всех этих делах заботятся 2 стороны: .... Вроде так нормальненько :)). Да нет, все так выразился. Просто вот наличие "специализированной DLL-синхронизатора" мне и не нравится. Совсем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2006, 18:00 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
White Owl БармолейМожет я выразился в прошлый раз не так. В итоге получается, что о всех этих делах заботятся 2 стороны: .... Вроде так нормальненько :)). Да нет, все так выразился. Просто вот наличие "специализированной DLL-синхронизатора" мне и не нравится. Совсем. А что плохого? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2006, 18:59 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
Бармолей White OwlДа нет, все так выразился. Просто вот наличие "специализированной DLL-синхронизатора" мне и не нравится. Совсем. А что плохого? Ну я уже писал что плохого.... Но если хочешь повторю: 1) тебе прийдется из основной программы звать эти самые Код: plaintext 1. 3) ненормальное завершение основной программы приведет к ненормальному завершению этого "синхронизатора" и у тебя получается та же самая проблема которую ты пытался решить вводя "синхронизатор", только уже на двух dll :) 4) еще одна dll в дистрибутиве, при этом не выполняющая никакой полезной функции. Синхронизация может быть конечно полезной, но с точки зрения основной задачи она не нужна. Лично я предпочту звать из основной программы пару функций Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2006, 19:31 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
А, понял. У тебя, выходит дело, уже есть такая система правил в проекте: 1) У всех dll должен быть инит и шатдаун 2) Если в одной dll используешь другую длл, то должен ей форвардить эти вызовы 3) Делаешь что-то типа подсчета ссылок, или еще как, но так чтобы 2 раза не заинититься и не зашатдауниться При таком раскладе да, уже есть место, где "всяко завершать", ну и тогда само собой просится сунуть ожидание потоков тоже в ту же шатдаун. Тут наверное нужны еще некие базовые классики, чтобы не повторять код... Ну а так как у меня нет такой глобальной системы, а вводить ее на данном этапе по ряду причин довольно проблемно, то пока что более локальным решением может быть сервис в виде отдельной dll, узко направленный конкретно на решение задач с потоками, то есть "синхронизатор" этот. На exe при этом ложится только задача обеспечения финального вызова Код: plaintext 1. Код: plaintext 1. По-моему тут во многом дело вкуса и проектной ситуации - на какой манер делать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2006, 14:54 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
БармолейА, понял. У тебя, выходит дело, уже есть такая система правил в проекте: 1) У всех dll должен быть инит и шатдаун 2) Если в одной dll используешь другую длл, то должен ей форвардить эти вызовы 3) Делаешь что-то типа подсчета ссылок, или еще как, но так чтобы 2 раза не заинититься и не зашатдауниться Нет, не правильно :) 1) Процедуры MyDLL_Init()/MyDLL_Shutdown() есть только у некоторых dll. Которым есть что инитить и шатдаунить :) Соотвественно в документации на эти dll явно сказано о необходимости этой пары (или только одной из) функций. 2) Никуда я ничего не форваржу. Если DllA использует DllB, а я из основной программы не обращаюсь к DllB, то соответсвенно мне совершенно до лампочки как DllA работает с DllB. У меня в программе есть DllA_Init() и DllA_Shutdown(). Все. Что там происходит внутри DllA меня не волнует. 3) Ну и соотвественно никаких подсчетов ссылок и ни о каких двойных ссылках я не забочусь. Если Dll не должна инитится дважды и/или должна обслуживать несколько программ одновременно, то она (dll) сама об этом заботится. Например создает мутекс во время своего Dll_Init и разбирается надо ли его удалять при Dll_Shutodown. Из основной программы я ничего не делаю совсем. БармолейПо-моему тут во многом дело вкуса и проектной ситуации - на какой манер делать. Это конечно да.... Просто подход который я описываю работает уже много-много лет, в очень-очень многих freeware/shareware и разных других ~ware рантайм-библиотеках :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2006, 18:01 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
White Owl БармолейА, понял. У тебя, выходит дело, уже есть такая система правил в проекте: 1) У всех dll должен быть инит и шатдаун 2) Если в одной dll используешь другую длл, то должен ей форвардить эти вызовы 3) Делаешь что-то типа подсчета ссылок, или еще как, но так чтобы 2 раза не заинититься и не зашатдауниться Нет, не правильно :) 1) Процедуры MyDLL_Init()/MyDLL_Shutdown() есть только у некоторых dll. Которым есть что инитить и шатдаунить :) Соотвественно в документации на эти dll явно сказано о необходимости этой пары (или только одной из) функций. 2) Никуда я ничего не форваржу. Если DllA использует DllB, а я из основной программы не обращаюсь к DllB, то соответсвенно мне совершенно до лампочки как DllA работает с DllB. У меня в программе есть DllA_Init() и DllA_Shutdown(). Все. Что там происходит внутри DllA меня не волнует. 3) Ну и соотвественно никаких подсчетов ссылок и ни о каких двойных ссылках я не забочусь. Если Dll не должна инитится дважды и/или должна обслуживать несколько программ одновременно, то она (dll) сама об этом заботится. Например создает мутекс во время своего Dll_Init и разбирается надо ли его удалять при Dll_Shutodown. Из основной программы я ничего не делаю совсем. 1) Так у тя еще и документация есть??!! :)) Ну ты это, вообще счастливчик, если она настолько приближена к реализации и при этом еще и в актуальном состоянии поддерживается. 2) Когда ты говоришь, что не форвардишь это имеется ввиду что экзехе пофиг что дальше сделает DLLA? Ну это круто, но ведь реально то все-таки будут возникать ситуации форварда. Вот например, есть у тебя цепочка использования EXE -> DllA -> DllB -> ... -> DllY -> DllZ. И вдруг DllZ, возьми себе да и реализуй новый функционал, где появляются потоки. Так автор DllZ должен сообщить своему другу, пишущему DllY: "ты теперь зови мне инит и шатдаун!", а тот автору DllX и т.д. вплоть до писателя экзешника. И вот, дописывая эту шатдаун, они только и должны будут, что вызвать шатдаун того, кого они используют. Про это я и говорил, что это форвардинг (он остается таковым даже если вызывающий модуль не вдается в то что происходит). 3) Когда ты говоришь "я не забочусь о подсчете ссылок" ты, вероятно имеешь ввиду вызывающую сторону, например экзешник. Ну а вызываемая сторона если только ее шатдаун и инит не сводятся к соответствующим форвардам, никуда не денется от того, чтобы как то позаботиться о возможности повторных вызовов. Поэтому, то что ты не делаешь контроль повторных вызовов означает скорее всего, что его делают другие. White Owl БармолейПо-моему тут во многом дело вкуса и проектной ситуации - на какой манер делать. Это конечно да.... Просто подход который я описываю работает уже много-много лет, в очень-очень многих freeware/shareware и разных других ~ware рантайм-библиотеках :) Клево :) Да, очень часто, когда кто-нибудь делал что-нибудь много-много лет, то он уже обычно и дальше продолжает в том же стиле, особенно если это приводит к результату, и в этом нет ничего плохого, если все это вполне работает. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2006, 19:55 |
|
||
|
Завершение потока путем окончания процесса
|
|||
|---|---|---|---|
|
#18+
Бармолей1) Так у тя еще и документация есть??!! :)) Ну ты это, вообще счастливчик, если она настолько приближена к реализации и при этом еще и в актуальном состоянии поддерживается. Конечно есть :) Нафига мне возится с недокументированным чужим произведением? Либо документация, либо исходники, а лучше и то и другое. Бармолей2) Когда ты говоришь, что не форвардишь это имеется ввиду что экзехе пофиг что дальше сделает DLLA? Ну это круто, но ведь реально то все-таки будут возникать ситуации форварда. Вот например, есть у тебя цепочка использования EXE -> DllA -> DllB -> ... -> DllY -> DllZ. И вдруг DllZ, возьми себе да и реализуй новый функционал, где появляются потоки. Так автор DllZ должен сообщить своему другу, пишущему DllY: "ты теперь зови мне инит и шатдаун!", а тот автору DllX и т.д. вплоть до писателя экзешника. И вот, дописывая эту шатдаун, они только и должны будут, что вызвать шатдаун того, кого они используют. Про это я и говорил, что это форвардинг (он остается таковым даже если вызывающий модуль не вдается в то что происходит).эээ.... ну в общем то да, все верно. Все именно так и происходит. Но! Есть одно такое очень сильное "но". :) Если DllZ изменился настолько что для новой версии DllZ нужно переписать DllY, то DllZ переименовывается в DllZ2 и в документации на нее появляется дополнительный текст "как мигрировать с DllZ на DllZ2". DllZ еще некоторе время поддерживается на тему исправления багов в ней (автор DllZ поддерживает две разных ветки!). Потом DllZ остается лежать в виде последнего билда... А в каждом дистрибутиве DllY будет пометка, что мол для версии DllY 1.2.3 использовалась DllZ, а начиная с DllY 1.3.0 будет использоваться DllZ2. И частенько соответсвующие версии DllZ* лежат в очередном дистрибутиве DllY. Это конечно не обязательное требование, это скорее правило хорошего тона. Но его придерживаются 99% всех писателей библиотек :) Бармолей3) Когда ты говоришь "я не забочусь о подсчете ссылок" ты, вероятно имеешь ввиду вызывающую сторону, например экзешник. Ну а вызываемая сторона если только ее шатдаун и инит не сводятся к соответствующим форвардам, никуда не денется от того, чтобы как то позаботиться о возможности повторных вызовов. Поэтому, то что ты не делаешь контроль повторных вызовов означает скорее всего, что его делают другие.Все верно. В общем, я тебе очень советую заглянуть на sourceforge.net, пошарься там по разным проектам. Обязательно найдешь что-нибудь вкусное и понаблюдай за развитием заинтересовавших проектов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.01.2006, 23:34 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=33462470&tid=2032159]: |
0ms |
get settings: |
11ms |
get forum list: |
21ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
180ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
| others: | 244ms |
| total: | 525ms |

| 0 / 0 |
