15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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

Автор: Philipp Weidmann

Пример показывает как встроить в приложение возможность создавать параллельные потоки, управлять ими и завершать их по средствам API вызовов. Конечно это не шедевр, но начать с этого примера стоит.

Компилятор: Visual Basic 5.0, 6.0.

 

Самый первый и важный - это вызов CreateThread :

Declare Function CreateThread Lib "kernel32" (ByVal lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long

Что она делает? Она создаёт новый поток в Вашем приложении. Параметры :

  • ByVal lpThreadAttributes As Any: Атрибуты потока. Обычно этот параметр равен SECURITY_ATTRIBUTES, но он не обязателен и поэтому можно просто использовать значение ByVal 0& .

  • ByVal dwStackSize As Long: Указывает Windows - сколько памяти необходимо отвести для потока. Он нам тоже не понадобится, поэтому используем ByVal 0& для этого параметра.

  • ByVal lpStartAddress As Long: Это самый важный параметр. Он указывает Windows - какая функция будет выполняться в качестве потока. Для использования этого параметра, нам потребуется оператор AddressOf, который может применяться к публичным функциям в публичных модулях. Итак, разместите свою потоковую функцию в модуле и для параметра lpStartAddress используйте AddressOf Ваша функция.

  • ByVal dwCreationFlags As Long: Флаг, с которым будет создаваться поток. Для использования этого параметра, найдите константу CREATE_* в API Вьювере (в файле clsThreading.cls). Очень даже интересен флаг CREATE_SUSPENDED , который позволяет Вам создвать поток в остановленном состоянии (не запущенном). Если Вам не нужен этот параметр, то используйте ByVal 0&.

  • lpThreadID As Long: Это ByRef параметр, который содержит ID создаваемого потока.

Функция CreateThread возвращает handle созданного потока. Этот handle подобен Window handle (hWnd). Он позволяет Вам управлять потоком. Если функция CreateThread вернула 0, то поток по каким либо причинам НЕ был создан.

Следующий важный API вызов - это SetThreadPriority :

Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Long, ByVal nPriority As Long) As Long

Устанавливает приоритет для указанного потока. Параметры :

  • ByVal hThread As Long: обработчик(handle) потока. Вы можете использовать значение, которое вернула функция CreateThread.

  • ByVal nPriority As Long: Приоритет, который будет установлен для потока. Обычно используются следующие значения: THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL и THREAD_PRIORITY_HIGHEST названия которых объясняют сами за себя.

Для получения текущего приоритеты потока используется GetThreadPriority.

Так же интересны два следующих вызова, SuspendThread и ResumeThread :

Declare Function SuspendThread Lib "kernel32" (ByVal hThread As Long) As Long

Declare Function ResumeThread Lib "kernel32" (ByVal hThread As Long) As Long

SuspendThread останавливает поток, а ResumeThread продолжает его выполнение. Параметры:

  • ByVal hThread As Long: обработчик(handle) потока, который мы хотим остановить/продолжить.

И последний вызов, это TerminateThread - завершение потока. Этот Вызов важен, потому что Вам необходимо завершить все потоки перед завершением Вашего приложения, а иначе может произойти ошибка.

Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long

Параметры :

  • ByVal hThread As Long: обработчик(handle) потока, который мы хотим завершить.

  • ByVal dwExitCode As Long: Код выхода (не нужен). Используем ByVal 0&.

 

СКАЧАТЬ ИСХОДНИК(~16Kb)