Что нового

AutThread - Некое подобие потоков в AutoIt

firex

AutoIT Гуру
Сообщения
943
Репутация
208
AutoIt: 3.3.8.1+
Версия: Concept

Категория: Вспомогательные функции, Процессы, Разное

Описание: Эта библиотека реализует возможность создания некого подобия потокам ( выполнение функций без остановки основного кода ). Скрипт дублирует себя и передает определенную информацию ( блокируя выполнение основного кода ), с помощью этой информации создается коммуникация между родительским процессом и "потоком" через память родителя.

Особенности:
1) В случае падения родителя, поток закроется автоматически ( двухстороннее слежение ).
2) После выполнения целевой функции поток вернет все результаты в родителя ( @Error, @Extended, Return value ).
3) Автоматическое восстановление значения исходя из его типа ( как и при передаче аргументов, так и при возврате значения Return ).
4) Максимальный буфер с аргументами/возвращаемым значением не должен превышать byte[4] ( dword ).
5) В случае, если ответ превышает размеры заданного вами буфера - он будет обрезан.
6) На данный момент передача массива не возможна, вместо него придет пустая строка.

Список функций:
Код:
; #CURRENT# 
;_AutThread_Create
;_AutThread_Kill
;_AutThread_IsAlive
;_AutThread_ParentThreadPID
;_AutThread_SelfIsThread
;_AutThread_ErrorCallbackRegister

; #INTERNAL_USE_ONLY#
;__AT_Init
;__AT_Main
;__AT_VarType
;__AT_ReinterpretCast
;__AT_TagSize
;__AT_OpenProcess
;__AT_ReadProcessMemory
;__AT_WriteProcessMemory
;__AT_CloseHandle
;__AT_OnExit

Пример:
Обязательно скомпилировать.
Код:
#Include <GUIEdit.au3>
#Include <StaticConstants.au3>
#Include <WindowsConstants.au3>

#Include "AutThread.au3"

Func _MsgBox( $iFlag = 0, $sTitle = "", $sText = "", $iTimeout = 0, $hWnd = 0 )
	Local $iRet = MsgBox( $iFlag, $sTitle, $sText, $iTimeout,$hWnd )
	If $iRet = -1 Then _
		SetError( Random( 1, 5, 1 ), Random( 5, 12, 1 ) )

	Return $iRet
EndFunc

Local $hGui, $aInput[6], $iButtonCreate, $iLog

$hGui = GUICreate( "Thread_Example1", 375, 240, -1, -1 )
	Local $t = GUISetFont( 9 ), $m = GUISetState( @SW_SHOW, $hGui )

GUICtrlCreateLabel( "Message box in Thread!", 5, 10, 355, 20, $SS_CENTER )
	GUICtrlSetFont( -1, 11 )

GUICtrlCreateLabel( "MsgBox("&@TAB&"  ,"&@TAB&@TAB&","&@TAB&@TAB&","&@TAB&","&@TAB&@TAB&")", 5, 40, 365, 20 )
	GUICtrlSetState( -1, 128 )

$aInput[1] = GUICtrlCreateInput( 64, 54, 39, 35, 20 )
$aInput[2] = GUICtrlCreateInput( "Title...", 97, 39, 65, 20 )
$aInput[3] = GUICtrlCreateInput( "Text...", 170, 39, 73, 20 )
$aInput[4] = GUICtrlCreateInput( 0, 251, 39, 32, 20 )
$aInput[5] = GUICtrlCreateInput( 0, 291, 39, 72, 20 )

$iButtonCreate = GUICtrlCreateButton( ">Create (MsgBox) thread<", 5, 65, 365, 30 )
$iLog = GUICtrlCreateEdit( "", 5, 100, 365, 135, 0x50200844 )
; ===
Local $Idx = 0, $aArgs[6] = [5], $iEval

_AutThread_ErrorCallbackRegister( "__OnError" )

While Sleep( 40 )
	Switch GUIGetMsg()
		Case -3
			Exit
		Case $iButtonCreate
			For $i = 1 To 5 Step 1
				$aArgs[$i] = GUICtrlRead( $aInput[$i] )
			Next
			_AutThread_Create( "_MsgBox", 2, "iResult" & $Idx, $aArgs )
			_GUICtrlEdit_AppendText( $iLog, "Thread #" & $Idx & " Created!" & @CRLF )
			$Idx += 1
	EndSwitch
	For $i = $Idx To 0 Step -1
		If IsDeclared( "iResult" & $i ) Then
			$iEval = Eval( "iResult" & $i )
			If $iEval Then
				_GUICtrlEdit_AppendText( $iLog, "Thread #" & $i & " Return=" & $iEval & @CRLF & _
					@TAB & "@Error=" & Eval( "iResult" & $i & "_err" ) & @CRLF & _
					@TAB & "@Extended=" & Eval( "iResult" & $i & "_ext" ) & @CRLF )
				Assign( "iResult" & $i, 0 )
			EndIf
		EndIf
	Next
WEnd

Func __OnError( $iAutThread )
	_GUICtrlEdit_AppendText( $iLog, "Thread #" & $iAutThread & " Crashed!" & @CRLF )
EndFunc

Файл: AutThread.au3

Источник: autoit-script.ru
Автор(ы): Firex
 

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Код:
AutThread.au3(60,38) : WARNING: $__tagAutThreadInfo: possibly used before declaration.
	$tagAutThread = $__tagAutThreadInfo &
Код:
AutThread.au3(65,40) : WARNING: $__tagAutThreadBody: possibly used before declaration.
			$tagAutThread &= $__tagAutThreadBody
Код:
AutThread.au3(83,28) : WARNING: $__tagATI_Size: possibly used before declaration.
	If $iTmp - $__tagATI_Size <
Код:
AutThread.au3(114,31) : WARNING: $__aAutThreads: possibly used before declaration.
		$Idx = $__aAutThreads[0][0] +


Добавлено:
Сообщение автоматически объединено:

Соответственно из примера ничего не получается
 
Автор
firex

firex

AutoIT Гуру
Сообщения
943
Репутация
208
MnM
Скомпилируйте, эти "Предупреждения" невозможно обойти с текущей логикой кода.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
firex
Всё конечно хорошо, но "Правила обязательного оформления публикаций" пока еще никто не отменял ;)
Будьте так любезны, оформите тему согласно шаблону.
P.S. Дополнения к стандартному шаблону не возбраняются, если они несут эстетическую или информационную ценность!


Добавлено:
Сообщение автоматически объединено:

firex [?]
А почему бы и нет!?
Массив это такая же переменная :smile:
 
Автор
firex

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Garrett [?]
А почему бы и нет!?Массив это такая же переменная
86Xrx.png
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
firex
Операция Ы сказал(а):
— А старушка засвистела?
— Не-е-т.
— Так что же Вы припёрлись?! Болван!
— Согласен.
Не Согласен! ;D
P.S. Видимо нужно обновить в памяти справку. :thanks:


Добавлено:
Сообщение автоматически объединено:

firex
Хотя!
Код:
#include<Array.au3>
$b = '1,2,3'
Assign('a', StringSplit($b, ','))
_ArrayDisplay(Eval('a'))

The name of the variable you wish to assign. Cannot be an array element.
Имя переменной, которую требуется назначить. Не может быть элементом массива.
 
Автор
firex

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Garrett
Этот трюк тут точно не поможет ;D

Единственный вариант - продублировать инициализацию переменных и констант в шапку UDF, однако мне проще проигнорировать эти предупреждения, они не мешают запускаться скрипту :smile:
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
Код:
$sCode = "MsgBox(64, 'info', 'worked!')"
Run(@AutoItExe&' /AutoIt3ExecuteLine "'&$sCode&'"')
; code...

:D
 
Автор
firex

firex

AutoIT Гуру
Сообщения
943
Репутация
208
alex33
Так не выполнить более одной строки кода. Да и результат в скрипт не вернуть. :smile:
 
Автор
firex

firex

AutoIT Гуру
Сообщения
943
Репутация
208
madmasles, CreatoR
Вы читали особенности? А пример смотрели? ;) Зачем человеку городить лишние дублирования функций в текстовом виде ( в теле скрипта ) с последующей ( ко всему прочему и открытой ) записью в файл? Суть этой UDF не в том ЧТО она делает, а в том КАК она это делает.

Исходя из ваших альтернатив можно убрать все UDF из AutoIt, какой от них толк, ведь всегда можно изобрести более худший велосипед "на лету". Само собой, подключать эту библиотеку ради MsgBox попросту смешно, однако в ситуациях касательных массовых операций над файлами/страницами она идеальна.


Как найдется время - планирую осуществить возможность "вытащить" значение переменной из потока или ее/их синхронизировать автоматически в момент выполнения скрипта.
 

vovsla

Осваивающий
Сообщения
607
Репутация
36
Не могу скачать AutThread.au3. Файл: AutThread.au3 - вложение не найдено
 

Olim98

Новичок
Сообщения
48
Репутация
2
Здраствуйте firex! Будете ли вы развивать UDF?
 
Автор
firex

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Olim98
Возможно, если появится время - сделаю поддержку массивов. А так в целом там развивать нечего, разве только реализовать автоматическую синхронизацию переменных между потоками.
 

Olim98

Новичок
Сообщения
48
Репутация
2
firex сказал(а):
Olim98
Возможно, если появится время - сделаю поддержку массивов. А так в целом там развивать нечего, разве только реализовать автоматическую синхронизацию переменных между потоками.
Было бы неплохо :-[
И если возможно добавьте пожалуйста запуск потока из другого потока. Также можно при запуске потока отключать его иконку в трее
Для добавления возможности работы AutThread в нескомпилированном виде замените строку:
Код:
$iAutThread = Run(@ScriptFullPath & ' /AutThreadInfo="' & @AutoItPID & ',' & Int($hMemory) & '" ' & $sCmdLine, @ScriptDir)

на
Код:
If @Compiled Then
	$iAutThread = Run(@ScriptFullPath & ' /AutThreadInfo="' & @AutoItPID & ',' & Int($hMemory) & '" ' & $sCmdLine, @ScriptDir)
Else
	$iAutThread = Run(@AutoItExe & ' /AutoIt3ExecuteScript "' & @ScriptFullPath & '" /AutThreadInfo="' & @AutoItPID & ',' & Int($hMemory) & '" ' & $sCmdLine, @ScriptDir)
EndIf


Кстати нашел странный баг, когда запускаешь поток без аргументов, то он сразу вылетает
 
Верх