Sign in to follow this  
Followers 0
E1M1

I made working multi threading but it randomly crashes as soon as it gets complicated

6 posts in this topic

#1 ·  Posted (edited)

I noticed that multi threaded msgbox works fine but multi threaded _GUICtrlEdit_AppendText doesnt work so fine anymore.

Usage:

1) save UDF as ThreadCreate.au3

2) Before you say that multithreading is impossible, run code below "Here's working Example"

3) If you want help me finding out what's wrong in my not working example, you can run this.

Remarks:

I've also noticed that when you put while loop in your threaded function, autoit crashes with out reason but when you just have huge amount code in threaded func, autoit usually gets some syntax error, but sometimes crashes.

Msgbox in last example works fine.

I wonder if anyone is interested in to try developing it any further.

UDF

#include <WinAPI.au3>

Func ThreadCreate($sFunc)
$hProc = openSecureProcess(@AutoItPID,0x001F0FFF)
;~ ConsoleWrite($hProc&@CRLF)
$hRegister = DllCallbackRegister ( $sFunc,"none", "")

;~ ConsoleWrite($hRegister&@CRLF)
$hfunc = DllCallbackGetPtr ( $hRegister )

ConsoleWrite("Func ptr "&$hfunc&@CRLF)
$hThread = CreateRemoteThread($hProc, 0, "", $hfunc, 0, "", "")
Sleep(10)
EndFunc

Func CreateRemoteThread($hProcess, $lpThreadAttributes, $dwStackSize, $lpStartAddress, $lpParameter, $dwCreationFlags, $lpThreadId)
    $call = DllCall("Kernel32.dll", "ptr", "CreateRemoteThread", _
            "ptr", $hProcess, _
            "ptr", $lpThreadAttributes, _
            "uint", $dwStackSize, _
            "ptr", $lpStartAddress, _
            "ptr", $lpParameter, _
            "dword", $dwCreationFlags, _
            "ptr", $lpThreadId)
    Return $call[0]
EndFunc   ;==>CreateRemoteThread

Func  openSecureProcess($wndpid,$rights)
    $SE_KERNEL_OBJECT = 6
    $DACL_SECURITY_INFORMATION = 0x00000004
    $ERROR_SUCCESS = 0
    $WRITE_DAC = 0x00040000
    $UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000

    Local $pid = $wndpid;
    Local $window;
    Local $process;
    Local $dacl = DllStructCreate("ptr");
    Local $secdesc = DllStructCreate("ptr");


      ; Try to open the process with the requested rights.
      $process =_WinAPI_OpenProcess($rights, 0, $pid);
      if($process <> 0) Then
         return $process;
      EndIf

      ; Get the DACL of this process since we know we have
      ; all rights in it. This really can't fail.
      if(GetSecurityInfo(_winapi_GetCurrentProcess(),  _
                         $SE_KERNEL_OBJECT, _
                         $DACL_SECURITY_INFORMATION, _
                         0, _
                         0, _
                         DllStructGetPtr($dacl,1), _
                         0, _
                         DllStructGetPtr($secdesc,1)) <> $ERROR_SUCCESS) Then
         return 0;
      EndIf

      ; Open it with WRITE_DAC access so that we can write to the DACL.
      $process =_WinAPI_OpenProcess($WRITE_DAC, 0, $pid);
      if($process == 0) Then
        _WinAPI_LocalFree($secdesc);
         return 0;
      EndIf

      if(SetSecurityInfo($process, _
                         $SE_KERNEL_OBJECT, _
                         BitOR($DACL_SECURITY_INFORMATION,$UNPROTECTED_DACL_SECURITY_INFORMATION), _
                         0, _
                         0, _
                         DllStructGetData($dacl,1), _
                         0) <> $ERROR_SUCCESS) Then
        _WinAPI_LocalFree($secdesc);
         return 0;
      EndIf

      ; The DACL is overwritten with our own DACL. We
      ; should be able to open it with the requested
      ; privileges now.
     _WinAPI_CloseHandle($process);
     _WinAPI_LocalFree($secdesc);
      $process =_WinAPI_OpenProcess($rights, 0, $pid);
      if($process == 0) Then
         return 0;
      EndIf

      return $process;
  EndFunc

  Func GetSecurityInfo($handle,$ObjectType,$SecurityInfo,$ppsidOwner,$ppsidGroup,$ppDacl,$ppSacl,$ppSecurityDescriptor )
    $call = DllCall("Advapi32.dll", "long", "GetSecurityInfo", _
            "ptr", $handle, _
            "int", $ObjectType, _
            "dword", $SecurityInfo, _
            "ptr", $ppsidOwner, _
            "ptr", $ppsidGroup, _
            "ptr", $ppDacl, _
            "ptr", $ppSacl, _
            "ptr", $ppSecurityDescriptor)
    Return $call[0]
EndFunc

  Func SetSecurityInfo($handle,$ObjectType,$SecurityInfo,$psidOwner,$psidGroup,$pDacl,$pSacl )
    $call = DllCall("Advapi32.dll", "long", "SetSecurityInfo", _
            "ptr", $handle, _
            "int", $ObjectType, _
            "dword", $SecurityInfo, _
            "ptr", $psidOwner, _
            "ptr", $psidGroup, _
            "ptr", $pDacl, _
            "ptr", $pSacl)
    Return $call[0]
EndFunc

Not working example (Random errors)

#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GuiEdit.au3>

#include "ThreadCreate.au3"

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 204, 381, 192, 114)
$Edit1 = GUICtrlCreateEdit("", 0, 0, 201, 377)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form2", 204, 381, 192+204, 114)
$Edit2 = GUICtrlCreateEdit("", 0, 0, 201, 377)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form2", 204, 381, 192+204+204, 114)
$Edit3 = GUICtrlCreateEdit("", 0, 0, 201, 377)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form4", 204, 381, 192+204+204+204, 114)
$Edit4 = GUICtrlCreateEdit("", 0, 0, 201, 377)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

ThreadCreate("Thread1")
ThreadCreate("Thread2")

While GUIGetMsg() <> $GUI_EVENT_CLOSE
    Sleep(10)
WEnd

Func Thread1()
    $i = 0;
    While 1
        $i += 1
    _GUICtrlEdit_AppendText($Edit1,"Thread1 Loop "&$i&@CRLF)
    If mod($i,1500) = 0 Then
        GUICtrlSetData($Edit1,"")
    EndIf

    WEnd
EndFunc

Func Thread2()
    $i = 0;
    While 1
        $i += 1
    _GUICtrlEdit_AppendText($Edit1,"Thread2 Loop "&$i&@CRLF)
    If mod($i,1500) = 0 Then
        GUICtrlSetData($Edit1,"")
    EndIf

    WEnd
EndFunc

Func Thread3()
    $i = 0;
    While 1
        $i += 1
    _GUICtrlEdit_AppendText($Edit1,"Thread3 Loop "&$i&@CRLF)
    If mod($i,1500) = 0 Then
        GUICtrlSetData($Edit1,"")
    EndIf

    WEnd
EndFunc

Func Thread14()
    $i = 0;
    While 1
        $i += 1
    _GUICtrlEdit_AppendText($Edit1,"Thread4 Loop "&$i&@CRLF)
    If mod($i,1500) = 0 Then
        GUICtrlSetData($Edit1,"")
    EndIf

    WEnd
EndFunc

Here's working Example

#include "ThreadCreate.au3"

ThreadCreate("Thread1")
ThreadCreate("Thread2")
ThreadCreate("Thread3")

Func Thread1()
MsgBox(0,0,"Thread 1")
EndFunc

Func Thread2()
    MsgBox(0,0,"Thread 2")
EndFunc

Func Thread3()
    MsgBox(0,0,"Thread 3")
EndFunc
Edited by E1M1

edited

Share this post


Link to post
Share on other sites



AutoIt is not multithread safe. You will constantly run into problems.

Share this post


Link to post
Share on other sites

Im a newb but I think that you can do a Bit of multithreading by cheating but you will run into error as it isnt safe for autoit to do it

because autoit doesnt the functionality coded into it .

is that somewhere along the lines of why autoit cannot do proper multithreading?

:graduated:


[center]First Ever Script/App[/center][center]Simple Battery Meter[/center]

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Interesting that the MsgBox code actually works (when you add the proper 'ptr' parameter), seeing how the interpreter is on a single thread.

When DllCallbackRegister() is called, it creates a code stub (mostly identical in each case) - so that is where each thread starts, not in actual script code.

Internally it redirects the script interpreter with each thread, but I wouldn't be clear on the details. But whatever the case, you can't do more than one thing inside those functions without the whole thing crashing. Its a pointless endeavor to try to pursue this any further E1M1, I hope you understand that. This is coming from someone who does know the *proper* way to create threads, and that even in those pre-assembled threads, no script variables can be accessed other that persistent DLLStructs().

The best you can hope to do with what you intend is to do multiprocessing. It achieves the same net results, except you have to understand inter-process (or inter-script) communication.

*edit: forgot 'MsgBox'

Edited by Ascend4nt

Share this post


Link to post
Share on other sites

I didn't catch it, what's diference between multiprocessing and multithreading.


edited

Share this post


Link to post
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
Sign in to follow this  
Followers 0