Современные решения

для защиты Windows приложений

и восстановления исходного кода
Автор: Vasya2000. Дата публикации: 20.08.2004

Многопотоковость в Visual Basic


Часто на форуме приходиться видеть вопросы, связанные с многопоточностью в VB. Это и как их создавать и как сделать так чтобы форма не зависала на время длительных операций. Вроде с этим проблем нет, но наиболее интересные вопросы у начинающих программистов (а порой и у опытных) возникают при создании своих моделей, заточенных под собственные нужды. Поскольку я и сам прошел через все это, то с интересом обнаруживаю, что этапы исследований в этой области практически у всех одинаковы. Самое первое, что обнаруживают все экспериментаторы - ошибку о недопустимой операции. Поскольку чисто психологически многие не решаются в потоке поставить длинный цикл (чтобы не терять свое драгоценное время), то они не успевают отследить момент, в который эта ошибка возникает. Следующим этапом является MsgBox. По идее, к нему начинают прибегать, чтобы вывести диагностическое сообщение из потока, чтобы убедиться, что он все-таки работает. Здесь многих ждет разочарование. К сожалению и эта функция, и многие другие встроенные VB-функции в потоках не работают, более того, они вызывают ошибку о недопустимой операции. Поэтому хочу сразу обратить ваше внимание на этот прискорбный факт. Но это конечно же не значит, что все потеряно. Дело в том, что АПИ функции - потоко-безопасные, и среди их многообразия найдутся достойные заменители стандартных VB-функций, в частности, вместо MsgBox можно использовать - MessageBox или MessageBoxEx. К сожалению об этом начинающие исследователи многопоточности VB еще не знают.

Итак, в теле потока не работают множество стандартных функций VB. Мне известно, что это MsgBox и функции обработки строк, кроме UCase и LCase.

Следующий момент - выход из потока. Я долго не мог понять, что происходит, и допускал те самые ошибки, о которых уже написал. Отказавшись от экспериментов я стал анализировать код Филлипа Вейдмана и обнаружил, что у него не предусмотрен выход из потока вообще, т.е. там стоит тупой вечный цикл. Зациклив свой пример, я перестал видеть эту ужасную ошибку о недопустимой операции, но, к сожалению, оказалось, что мои потоки с вечными циклами продолжают болтаться в памяти, в списках процессов, даже несмотря на то, что основная форма уже выгружена. Пришлось читать MSDN по сабжу. Среди всяких интересных функций мне приглянулась TerminateThread, наверное своим бескомпромиссным Terminate. Поставив ее в конец своей потоковой функции, я наконец таки добился более-менее корректного выхода из потока. Но.

Теперь обнаружилось, что если закрывать основную форму - опять вылетает эта ошибка о недопустимой операции!! Прокричав гневные ругательства в адрес всех разработчиков и идеологов VB, я скопировал удачное решение завершения потока в завершение работы формы в Form_Unload. Все заработало.

Пример который я делал был предназначен для демонстрации работоспособности "принципа пяти окон", предложенного Lamer'ом, при обсуждении неубиваемой программы в одной из тем на самом первом форуме. Поэтому, в нем кроме работы потоков присутствуют и синхронизация при помощи мьютексов и запуск приложений при помощи АПИ CreateProcess. Но все же основной лейтмотив - работа с потоками и лавирование между несовершенством механизмов VB при работе с ними. Вдумчивый читатель, надеюсь, без труда вникнет в эти тонкости и сделает соответствующие выводы, о том где уместно использовать VB, а где более подходящие языки программирования.

Напоследок хочу добавить о функции TerminateThread. Ее работа немного различна на различных платформах. К примеру в NT, перед вызовом этой функции необходимо закрыть все дескрипторы, и открытые файлы. Иначе они так и останутся открытыми, система их не будет закрывать, а это влечет за собой нерациональное использование ресурсов. Об этом и о многом другом можно узнать из MSDN. З.Ы. Пример нужно откомпилировать и запускать только откомпилированным.

Как он работает: приложение создает мьютекс и запускает поток. Поток пытается завладеть мьютексом и в случае удачи каждые 600 миллисекунд просматривает список процессов. В них он пытается найти себя и считает количество своих копий. Если их меньше 5 то запускает сам себя. Если пытаться остановить выполнение активной программы, то мьютекс освобождается и им пытаются овладеть другие копии приложения. Овладев им история повторяется. Чтобы остановить этот беспредел нужно остановить потоки на всех неактивных копиях, ожидающих освобождения мьютекса воспользовавшись кнопкой на форме <Остановить поток>. После этого остановить или выгрузить активное приложение. Желаю удачи в изучении многопоточности.

Комментарии

отсутствуют

Добавление комментария


Ваше имя (на форуме):

Ваш пароль (на форуме):

Комментарии могут добавлять только пользователи,
зарегистрированные на форуме данного сайта. Если Вы не
зарегистрированы, то сначала зарегистрируйтесь тут

Комментарий: