Jump to content

Multi-Threading


c0d3x
 Share

Recommended Posts

Here's a cool trick I found for multithreading, thought many here may find it useful.

$Handle1 = DllCallbackRegister("ThreadTest1", "int", "ptr")
$Handle2 = DllCallbackRegister("ThreadTest2", "int", "ptr")
Func CreateThread($Handle, $struct)
$return = DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", DllCallbackGetPtr($Handle), "ptr", DllStructGetPtr($struct), "long", 0, "int*", 0)
Return $return[0]
EndFunc
$Struct1 = DllStructCreate("Char[200];int")
DllStructSetData($Struct1, 1, 10)
CreateThread($Handle1, $Struct1)
$Struct2 = DllStructCreate("Char[200];int")
DllStructSetData($Struct2, 1, 10)
CreateThread($Handle2, $Struct2)
MsgBox(0x40, "Thread 1", "Default Thread")
Func ThreadTest1($x)
$y = DllStructCreate("char[200];int", $x)
MsgBox(0x40, "Thread 2", "Added Thread #1")
EndFunc ;==>_ThreadStart
Func ThreadTest2($x)
$y = DllStructCreate("char[200];int", $x)
MsgBox(0x40, "Thread 3", "Added Thread #2")
EndFunc ;==>_ThreadStart
Link to comment
Share on other sites

$Handle1 = DllCallbackRegister("ThreadTest1", "int", "ptr")
$Handle2 = DllCallbackRegister("ThreadTest2", "int", "ptr")


Func CreateThread($Handle, $struct)
$return = DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", DllCallbackGetPtr($Handle), "ptr", DllStructGetPtr($struct), "long", 0, "int*", 0)
Return $return[0]
EndFunc   ;==>CreateThread


$Struct1 = DllStructCreate("Char[200];int")
DllStructSetData($Struct1, 1, 10)
CreateThread($Handle1, $Struct1)


$Struct2 = DllStructCreate("Char[200];int")
DllStructSetData($Struct2, 1, 10)
CreateThread($Handle2, $Struct2)


While 1
Sleep(10)
WEnd


Func ThreadTest1($x)
$y = DllStructCreate("char[200];int", $x)
$i = 0
While 1
MsgBox(0, $i, "Thread #1")
$i += 1
WEnd
EndFunc   ;==>ThreadTest1


Func ThreadTest2($x)
$y = DllStructCreate("char[200];int", $x)
$i = 0
While 1
MsgBox(0, $i, "Thread #2")
$i += 1
WEnd

EndFunc   ;==>ThreadTest2
Why Thread#1 MsgBox vanishes ?

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

The While Loop should make the Thread #1 MsgBox and Thread #2 Msgbox comeup independently

That is when OK is pressed in Thread#2 Msgbox another Thread#2 Msgbox is shown and similarly with Thread#1 Msgbox.

But it doesn't seem to work likewise.

Do I have a misconception ?

Edited by PhoenixXL

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

The While Loop should make the Thread #1 MsgBox and Thread #2 Msgbox comeup independently

That is when OK is pressed in Thread#2 Msgbox another Thread#2 Msgbox is shown and similarly with Thread#1 Msgbox.

But it doesn't seem to work likewise.

Do I have a misconception ?

Do you mean like this?

Func CreateThread($Handle, $struct)
$return = DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", DllCallbackGetPtr($Handle), "ptr", DllStructGetPtr($struct), "long", 0, "int*", 0)
Return $return[0]
EndFunc ;==>CreateThread


While 1
$Handle1 = DllCallbackRegister("ThreadTest1", "int", "ptr")
$Handle2 = DllCallbackRegister("ThreadTest2", "int", "ptr")
$Struct1 = DllStructCreate("Char[200];int")
DllStructSetData($Struct1, 1, 10)
CreateThread($Handle1, $Struct1)
$Struct2 = DllStructCreate("Char[200];int")
DllStructSetData($Struct2, 1, 10)
CreateThread($Handle2, $Struct2)
sleep(1000)
WEnd


Func ThreadTest1($x)
$y = DllStructCreate("char[200];int", $x)
$i = 0
While 1
MsgBox(0, $i, "Thread #1")
$i += 1
WEnd
EndFunc ;==>ThreadTest1


Func ThreadTest2($x)
$y = DllStructCreate("char[200];int", $x)
$i = 0
While 1
MsgBox(0, $i, "Thread #2")
$i += 1
WEnd

EndFunc ;==>ThreadTest2
Link to comment
Share on other sites

No. I just want Two MessageBox i.e. of Thread#1 and Thread#2 at every point of time the script is running

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

@c0d3x

It would be nice to share something that you master, I see too many "magic numbers" and maybe two useless lines.

No offence here, it's better to know what we are doing instead of pasting code that we don't understand how it works (not talking directly to you) ;)

Br, FireFox.

Edited by FireFox
Link to comment
Share on other sites

@PhoenixXL

Do you mean that when you close the "Default Thread" MsgBox, then another MsgBox, the last one vanishes?

This is normal, any thread created with this example is not inherited by the application so if the main thread is ended then the application exits.

PS: I hope I'm right, it seems logical to me.

Edit: Erm... no as the application should exit when you directly close the "Default Thread" MsgBox.

Edit2: I tried to clean the code but there is two issues :

-It's not possible to declare the $aRet variable.

-I don't know how to convert a DLLStruct pointer to a DLLStruct.

#include <Constants.au3>

Local $hCallBack1 = DllCallbackRegister("_Thread1", "int", "ptr")
Local $hCallBack2 = DllCallbackRegister("_Thread2", "int", "ptr")

Local $tStruct1 = DllStructCreate("int")
DllStructSetData($tStruct1, 1, 5)

_WinAPI_CreateThread($hCallBack1, $tStruct1)

_WinAPI_CreateThread($hCallBack2)

MsgBox($MB_APPLMODAL, "Thread 0", "Default Thread")

Func _Thread1($lpParam)
;~ ConsoleWrite(DllStructGetData($lpParam, 1) & @crlf)
    MsgBox($MB_APPLMODAL, "Thread 1", "Added Thread #1")

    Return 1
EndFunc   ;==>ThreadTest1

Func _Thread2($lpParam)
    MsgBox($MB_APPLMODAL, "Thread 2", "Added Thread #2")

    Return 1
EndFunc   ;==>ThreadTest2

Func _WinAPI_CreateThread($hStartAddress, $tParameter = 0)
    Local $pParameter = 0
    If VarGetType($tParameter) = "DLLStruct" Then $pParameter = DllStructGetPtr($tParameter)

    $aRet = DllCall("kernel32.dll", "hwnd", "CreateThread", _
            "ptr", 0, _
            "dword", 0, _
            "long", DllCallbackGetPtr($hStartAddress), _
            "ptr", $pParameter, _
            "long", 0, _
            "int*", 0)

    If @error Or Not $aRet[0] Then
        Return SetError(1, 0, 0)
    EndIf

    Return $aRet[0]
EndFunc   ;==>_WinAPI_CreateThread

Br, FireFox.

Edited by FireFox
Link to comment
Share on other sites

Through a thread

  • Independent execution takes place until the Default thread is closed. Right ?
  • So if there is a Loop of MsgBox in Thread#1 and Thread#2, Whenever I press OK in thread#1 loop I should get another thread#1 Msgbox and vice-versa. But that doesn't seem to happen likewise.
#include <Constants.au3>


Local $hCallBack1 = DllCallbackRegister("_Thread1", "int", "ptr")
Local $hCallBack2 = DllCallbackRegister("_Thread2", "int", "ptr")

Local $tStruct1 = DllStructCreate("int")
DllStructSetData($tStruct1, 1, 5)

_WinAPI_CreateThread($hCallBack1, $tStruct1)

_WinAPI_CreateThread($hCallBack2)

MsgBox($MB_APPLMODAL, "Thread 0", "Default Thread")

Func _Thread1($lpParam)
Local $tStruct = DllStructCreate("int", $lpParam)
$tStruct = DllStructGetData($tStruct, 1)
;Maybe This way we could cast the struct pointer back to integer. Maybe there are better ways.
ConsoleWrite($tStruct & @CRLF)

;Since the MsgBox is in the Loop, if I press OK button in the following
;Msgbox I should receive another MsgBox from the Same Thread
While 1
MsgBox($MB_APPLMODAL, "Thread 1", "Added Thread #1")
WEnd

Return 1
EndFunc ;==>_Thread1

Func _Thread2($lpParam)
;Since the MsgBox is in the Loop, if I press OK button in the following
;Msgbox I should receive another MsgBox from the Same Thread
While 1
MsgBox($MB_APPLMODAL, "Thread 2", "Added Thread #2")
WEnd

Return 1
EndFunc ;==>_Thread2

Func _WinAPI_CreateThread($hStartAddress, $tParameter = 0)
Local $pParameter = 0
If VarGetType($tParameter) = "DLLStruct" Then $pParameter = DllStructGetPtr($tParameter)

$aRet = DllCall("kernel32.dll", "hwnd", "CreateThread", _
"ptr", 0, _
"dword", 0, _
"long", DllCallbackGetPtr($hStartAddress), _
"ptr", $pParameter, _
"long", 0, _
"int*", 0)

If @error Or Not $aRet[0] Then
Return SetError(1, 0, 0)
EndIf

Return $aRet[0]
EndFunc ;==>_WinAPI_CreateThread

When you press OK in thread#2 MsgBox, thereafter thread#2 msgbox disappears and in place now there are two thread#1 Msgbox with the default msgbox. I don't understand why this happens ?

Edited by PhoenixXL

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

Well, I would guess a dev could say more to this, but afaik this approach will not work as intended (I remember something about AutoIt not beeing thread safe). CreateThread calls a pointer to execute, in this case the callback, and again afaik, the callback unhooks the windows message queue of the whole program (stability precaution?), rendering everything unresponsive.

What seems to work is to call assembler code via CreateThread, here's an excellent example application by ward:

What we really would need is a AutoIt to ASM compiler I guess (just an idea, but I guess that's far, far out of reach).

Link to comment
Share on other sites

  • 5 months later...

iim working with 4 parallel treads, and works perfectly.

im using "corutine"   of   neogia and ParoXsitiC

 

I've taken a look at that UDF, it does not create new threads but spawns new processes, so no multithreading but more multiprocessing.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...