Что нового

Мультипоточность

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
В справке PureBasic написано, что процедура, которую вы используете в качестве потока, должна принимать один параметр и не может ничего возвращать.
Почему? Вот два простых примера (разница только в проверке существования потока):
Код:
#STILL_ACTIVE = 259

Procedure _TestProcedure(*Value)
  Delay(Random(4000, 2000))
  ProcedureReturn *Value
EndProcedure

iExitCode.l
*pExitCode = @iExitCode

iThread =  CreateThread(@_TestProcedure(), 123)
Debug "iThread: " + iThread
hThread.i = ThreadID(iThread)
Debug "hThread: " + hThread
Repeat
  Delay(500)
  Debug "GetExitCodeThread_: " + GetExitCodeThread_(hThread, *pExitCode)
  Debug "ExitCode: " + iExitCode
Until iExitCode <> #STILL_ACTIVE

Debug "---"
Debug "CloseHandle_: " + CloseHandle_(hThread)
Код:
Procedure _TestProcedure(*Value)
  Delay(Random(4000, 2000))
  ProcedureReturn *Value
EndProcedure

iExitCode.l
*pExitCode = @iExitCode

iThread =  CreateThread(@_TestProcedure(), 123)
Debug "iThread: " + iThread
hThread.i = ThreadID(iThread)
Debug "hThread: " + hThread
Repeat
  Delay(500)
  Debug "Working..."
Until IsThread(iThread) = 0
Debug "---"
Debug "GetExitCodeThread_: " + GetExitCodeThread_(hThread, *pExitCode)
Debug "ExitCode: " + iExitCode
Debug "CloseHandle_: " + CloseHandle_(hThread)
ИМХО, авторы справки не могли не знать об этом.
И почему в справке не указано, что надо закрывать handle, возвращаемый функцией ThreadID()?

PS
Первым способом можно проверять работу потока и получать результат (ProcedureReturn) в AutoIt из DLL на PureBasic.
 

Prog

Продвинутый
Сообщения
597
Репутация
77
madmasles [?]
не может ничего возвращать
Это работает в винде, но не факт что будет работать в Linux и MacOS X.


И почему в справке не указано, что надо закрывать handle, возвращаемый функцией ThreadID()
Закрывать не нужно, точнее не обязательно. http://autoit-script.ru/index.php?topic=19954.msg118738#msg118738
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
В PB не нужно закрывать потоки хотя бы потому, что для этого тупо нет функций. Если вы используете API для открытия потока - OpenThread_(), то, естественно, поток необходимо будет закрыть посредством CloseHandle_(), чтобы уменьшить внутренний счетчик хэндла и освободить ресурсы, связанные с этим хэндлом.

madmasles сказал(а):
Первым способом можно проверять работу потока и получать результат (ProcedureReturn) в AutoIt из DLL на PureBasic.
Не понял, каким образом можно получать результат.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied [?]
каким образом можно получать результат.
Код dll:
Код:
Procedure.l _TestThread(*t_Data)
  Delay(Random(5000, 2000))
  ProcedureReturn *t_Data
EndProcedure

ProcedureDLL.i _Test(i_Return.l)
  Protected i_Thread.i, h_Thread.i
  
  i_Thread = CreateThread(@_TestThread(), i_Return)
  h_Thread = ThreadID(i_Thread)
  ProcedureReturn h_Thread
EndProcedure
Использование dll:
Код:
Global $hDll, $hThread, $iExitCode, $aRes

$hDll = DllOpen(@ScriptDir & '\test_dll.dll')
$aRes = DllCall($hDll, 'handle', '_Test', 'int', 22)
If (@error) Or (Not $aRes[0]) Then Exit 1
$hThread = $aRes[0]
Do
	Sleep(250)
	$aRes = DllCall('kernel32.dll', 'int', 'GetExitCodeThread', 'handle', $hThread, 'dword*', 0)
	If (@error) Or (Not $aRes[0]) Then
		ConsoleWrite('!Error GetExitCodeThread' & @LF)
		ContinueLoop
	EndIf
	$iExitCode = $aRes[2]
	ConsoleWrite('ExitCode: ' & $iExitCode & @LF)
Until $iExitCode <> 259

$aRes = DllCall('kernel32.dll', 'int', 'CloseHandle', 'handle', $hThread)
If (@error) Or (Not $aRes[0]) Then Exit 2
ConsoleWrite('CloseHandle: ' & $aRes[0] & @LF)
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Так это просто ExitCodeThread. В любом случае, как правило вызов потока из AutoIt предусматривает обмен данными в процессе выполнения этого потока. А если так, то все проверки, включая коды завершения, можно впихнуть в общий процесс обмена данными - структуру.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
madmasles сказал(а):
Тем не менее возвращается значение ProcedureReturn из потока.
Ну так и должно быть. То, что в PB об этом ни слова, связано скорее всего с его кроссплатформенностью. Там даже функции такой нет.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied [?]
все проверки, включая коды завершения, можно впихнуть в общий процесс обмена данными - структуру.
У меня есть dll, которая производит определенную проверку данных в несколько потоков. Я задаю в начале кол-во потоков и указатель на кусок памяти, полученный через Heap* API функции. Возможны 5 вариантов проверки, и мне удобнее получать их через ExitCodeThread. Дальше я просто записываю в пять разных файлов данные из памяти с определенным смещением через WriteFile API.
 
Верх