Нить в Visual Basic 6, Basic, Програмування, статті

Переклад Tower, www.VBstep.ru

Введення

Потоки використовуються для створення середовища виконання завдань, коли необхідно виконувати кілька завдань паралельно один з одним. Час, який витрачається процесором на виконання завдання, розподіляється між різними потоками згідно їх пріоритету. Це означає, що потокам з високим пріоритетом буде виділятися більше часу.

Як тільки потік запускається, він починає виконуватися. При цьому він виконується постійно, але може бути примусово зупинено. Внутрішня будова потокових функцій представляється циклічної структурою. Цей цикл буде виконуватися до тих пір, поки не отримати відповідний сигнал про припинення виконання. Час, через яке перевіряється сигнал на знищення потоку, може бути змінено. Це може бути використано, якщо існує якийсь критично для виконання код, робота якого не повинна перериватися іншими потоками.

Застосування

Для прикладу розглянемо роботу двох потоків, запущених в одному адресному просторі.
AddressOf дозволяє нам визначити адреси для функцій в потоках.
lThreadHandle1 і lThreadHandle2 – покажчики на потоки, які в подальшому можуть бути використані для їх закриття

lThreadHandle1 = CreateThread(ByVal 0&, ByVal 0&, _
			AddressOf test_function, _
			ByVal 0&, 0, lpThreadID)
lThreadHandle2 = CreateThread(ByVal 0&, ByVal 0&, _
			AddressOf test_function2, _
			ByVal 0&, 0, lpThreadID)

Після цього створюємо нову подію і инициализируем його:

lEventHandle = CreateEvent(ByVal 0&, False, False, ByVal 0&)
lRC = SetEvent(lEventHandle)

Функція WaitForSingleObject отримує покажчик на сигнал і і час його очікування в мілісекунди. Сигнал буде повертати якесь значення, відмінне від 0.
Приклад використання функції:

ret = WaitForSingleObject(lEventHandle, 10)

Попередження при роботі:

Приклад програми на Visual Basic
Створюємо модуль, який містить дві функції – test_function і test_function2, кожна з яких буде виконуватися у власному потоці. Кожен потік буде мати критичний код, під час якого потік не буде закриватися при отриманні сигналу. Потік буде закриватися лише в тому випадку, якщо критичний код буде закінчений.

Option Explicit
Public 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
Public Declare Sub Sleep Lib "kernel32" _
			(ByVal dwMilliseconds As Long)
Public Declare Function TerminateThread Lib "kernel32" _
			(ByVal hThread As Long, _
			ByVal dwExitCode As Long) As Long
Public Declare Function TerminateProcess Lib "kernel32" _
			(ByVal hProcess As Long, _
			ByVal uExitCode As Long) As Long
Public Declare Function GetCurrentProcess Lib "kernel32" () As Long
Public Declare Function WaitForSingleObject Lib "kernel32.dll" _
			(ByVal hHandle As Long, _
			ByVal dwMilliseconds As Long) As Long
Public Declare Function CreateEvent& Lib "kernel32" _
			Alias "CreateEventA" _
			(ByVal lpEventAttributes As Long, _
			ByVal bManualReset As Long, _
			ByVal bInitialState As Long, _
			ByVal lpname As String)
Public lThreadHandle1 As Long
Public lThreadHandle2 As Long
Public lEventHandle As Long
Public Sub Main()
	frmOutput.Show
End Sub
Public Sub test_function()
	Dim i As Long
	Dim ret As Long
	i = 0
	Do
	i = i + 1
	 'Заснули на 10
	frmOutput.txtStream1 = i
	
	DoEvents
	ret = WaitForSingleObject(lEventHandle, 10)
	Loop Until ret = 0
End Sub
Public Sub test_function2()
	Dim i As Long
	Dim ret As Long
	i = 0
	Do
	i = i + 1 'Заснули на 500
	frmOutput.txtStream2 = i
	ret = WaitForSingleObject(lEventHandle, 500)
	Loop Until ret = 0
End Sub

Тепер створюємо форму.
У формі створюємо два кнопки, які будуть зупиняти й запускати потоки. Перша кнопка створює два різних потоку для двох функцій, які описані в модулі, а також об’єкт події, який використовується для зупинки потоків. Друга кнопка використовується для зупинки і закриття всіх активних потоків. При виході з форми закриваються всі потоки.

Private Sub cmdStart_Click()
	Dim lpThreadID As Long
	lThreadHandle1 = CreateThread(ByVal 0&, _
				ByVal 0&, _
				AddressOf test_function, _
				ByVal 0&, 0, lpThreadID)
	lThreadHandle2 = CreateThread(ByVal 0&, _
				ByVal 0&, _
				AddressOf test_function2, _
				ByVal 0&, 0, lpThreadID)
	lEventHandle = CreateEvent(ByVal 0&, _
				False, False, ByVal 0&)
End Sub
Private Sub cmdStop_Click()
	Dim lRC As Long
	
	lRC = SetEvent(lEventHandle)
	
	If lThreadHandle1 > 0 Then
		Call TerminateThread(lThreadHandle1, ByVal 0&)
	End If
	If lThreadHandle2 > 0 Then
		Call TerminateThread(lThreadHandle2, ByVal 0&)
	End If
	
	lThreadHandle1 = 0
	lThreadHandle2 = 0
End Sub
Private Sub Form_Unload(Cancel As Integer)
	If lThreadHandle1 > 0 Then
		Call TerminateThread(lThreadHandle1, ByVal 0&)
	End If
	If lThreadHandle2 > 0 Then
		Call TerminateThread(lThreadHandle2, ByVal 0&)
	End If
	Call TerminateProcess(GetCurrentProcess, ByVal 0&)
End Sub

Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*