Sign in to follow this  
Followers 0
ChrisL

Faking Multi Threading

7 posts in this topic

I should have put this in scripts and scraps originally.. sorry.. Mods can delete the one from Support if you like :o

OK whats your opinion on this, a few people have asked about multi threading and sugestions are usually run 2 exe's and a text file to communicate

What about having one exe which writes a new AU3 file and then runs it..

and the way you talk to the main application and return a value is by using TCP/IP to send/receive a message. The adlib check for a new message periodically. (The tcp stuff is based on AutoIT Smiths stuff again.. thanks dude!)

I've just tried it with creating a simple second app that just sends a line of text back but I think it could be used for greater things.

; ----------------------------------------------------------------------------
;
; AutoIt Version: 3.1.103 beta
; Author:        Chris Lambert
;
; Script Function:
;   Template AutoIt script.
;
; ----------------------------------------------------------------------------

; Script Start - Add your code below here

AdlibEnable ( "Adlib" , 1000 )
$Port = 8001
Global $MaxConc = 100
$IPAddress = @IPAddress1
Global $MainSocket = TCPStartServer($Port, $MaxConc)
If @error <> 0 Then Exit MsgBox(16, "Error", "Server unable to initialize." & @crlf & _
        "Check the correct network card is set and port is not already in use" & @crlf & _
        "Selected network card address is :" & $IPAddress & " Port number is :" & $Port)
Global Const $MaxLength = 512
Global $ConnectedSocket[$MaxConc]
Global $CurrentSocket = 0
Local $Track = 0
Global Const $MaxConnection = ($MaxConc - 1)

For $Track = 0 To $MaxConnection Step 1
    $ConnectedSocket[$Track] = -1
Next

;; This section writes the new file and then runs it
$NewTempFile = @Hour & @Min & @sec & ".Au3"
FileWriteLine ($NewTempFile,'MsgBox (0,@scriptname,"I am the new file running and the main program is still doing its own thing")')
FileWriteLine ($NewTempFile, 'Global $windowTitle')
FileWriteLine ($NewTempFile, '$Port = 8001')
FileWriteLine ($NewTempFile, 'Global $MainSocket')
FileWriteLine ($NewTempFile,';perform some actions here then send the data back to the main application')
FileWriteLine ($NewTempFile,'       SendData("Info I want to send back to main application");Send data back')
FileWriteLine ($NewTempFile,'Func SendData($Data)')
FileWriteLine ($NewTempFile,'   TCPStartup()')
FileWriteLine ($NewTempFile,'   $MainSocket = TCPConnect(TCPNameToIP(@computername), $Port)')
FileWriteLine ($NewTempFile,'   If $MainSocket = -1 Then;send message success first attempt')

FileWriteLine ($NewTempFile,'       While $MainSocket = -1')
FileWriteLine ($NewTempFile,'           $MainSocket = TCPConnect(TCPNameToIP(@computername), $Port)')
FileWriteLine ($NewTempFile,'           If $MainSocket <> - 1 Then ExitLoop;exit for loop')
FileWriteLine ($NewTempFile,'               Sleep (1000)')
FileWriteLine ($NewTempFile,'           Wend')
FileWriteLine ($NewTempFile,'   Endif')
FileWriteLine ($NewTempFile,'           TCPSend($MainSocket, $Data)')
FileWriteLine ($NewTempFile,'EndFunc;==>SendData')

FileWriteLine ($NewTempFile,'Func OnAutoItExit()')
FileWriteLine ($NewTempFile,'   TCPCloseSocket($MainSocket)')
FileWriteLine ($NewTempFile,'   TCPShutdown()')
FileWriteLine ($NewTempFile,'EndFunc;==>OnAutoItExit')
;;end of new file generation

Run(@AutoItExe & ' /AutoIt3ExecuteScript ' & $NewTempFile)
    For $i = 1 to 10
    MsgBox (0,"Main", "I am the main program",1)
    Next


Func Adlib()
            $ConnectedSocket[$CurrentSocket] = TCPAccept($MainSocket)
            If $ConnectedSocket[$CurrentSocket] <> - 1 Then
                $CurrentSocket = SocketSearch()
            EndIf
            $Track = 0
            For $Track = 0 To $MaxConnection Step 1
                If $ConnectedSocket[$Track] <> - 1 Then
                    $Data = TCPRecv($ConnectedSocket[$Track], $MaxLength)
                    If StringRight($Data, 4) = "~bye" Then
                        TCPCloseSocket($ConnectedSocket[$Track])
                        $ConnectedSocket[$Track] = -1
                        $CurrentSocket = SocketSearch()
                    ElseIf $Data <> "" Then
                        ReceivedData($Data)
                    EndIf
                EndIf
            Next
EndFunc

Func ReceivedData($Cmd)
MsgBox (0,"My received Data", $CMD)
EndFunc;==>ReceivedData

Func SocketSearch()
    Local $Track = 0
    For $Track = 0 To $MaxConnection Step 1
        If $ConnectedSocket[$Track] = -1 Then
            Return $Track
        Else
; Socket In Use
        EndIf
    Next
EndFunc;==>SocketSearch

Func TCPStartServer($Port, $MaxConnect = 1)
    Local $Socket
    $Socket = TCPStartup()
    Select
        Case $Socket = 0
            SetError(@error)
            Return -1
    EndSelect
    $Socket = TCPListen($IPAddress, $Port, $MaxConnect)
    Select
        Case $Socket = -1
            SetError(@error)
            Return 0
    EndSelect
    SetError(0)
    Return $Socket
EndFunc;==>TCPStartServer

Share this post


Link to post
Share on other sites



You could also use StdIn/Out reading and writing since you're running one program from within another.

Share this post


Link to post
Share on other sites

Hmmmmm, interesting.

Maybe make a preprocessor, somthing like

While @error <> 1
   $read = Filereadline( $file )
   If $read = "MultiThread" Then
       while $read <> "endmultithread"
           $file2 = fileopen( @random file name )
           $read = Filereadline( $file )
           filewriteline( $file2, $read )
      WEnd
   EndIf
Wend


            
        

        
            
                

    
        
            
        
    


            
        

        
            
                
                
                
            
            
                
            
        
        
            




  
  
    [center][/center]Working on the next big thing.Currently Playing: Halo 4, League of LegendsXBL GT: iRememberYhslaw
  


        
    

    
        
            Share this post
            
Link to post
            
            
            

            
                Share on other sites
                

    
        
            

    

        
            

    

        
            

    

        
            

    

        
    

            
        
    


    

                    
                
                    
                    
                    






    
    
        
themax90   

    
        
    
             2
    
        
    

        
            
                A new beginning
            
            

            
                

    
        
    

            
            Active Members
            
            
                

    
        
    
             2
    
        
    

                1,209 posts
                
                

            
        
    
    
        


    

    
        
            
            
                
            
            
        

        
    #4 · 
            Posted 
            
            
            
        
    

    


            
        
            What you can do, perhaps, is always have a script as a server, running to check for messages, but having a syntax to send messages.  Such as ~send-ip-port-data, and upon recv will shutdown the server temporarily to send that message, and reboot the server quickily after, and this shouldn't take more then 0.0046 seconds, honestly, so that could be a way.

Example:
Global Const $Port = 50911
Global $MaxConc = 100
Global $MainSocket = TCPStartServer($Port, $MaxConc)
If @error <> 0 Then Exit MsgBox(16, "Error", "Server unable to initialize.")
Global Const $MaxLength = 512
Global $ConnectedSocket[$MaxConc]
Global $CurrentSocket = 0
Local $Track = 0
Global Const $MaxConnection = ($MaxConc - 1)
For $Track = 0 To $MaxConnection Step 1
    $ConnectedSocket[$Track] = -1
Next
While 1
    $ConnectedSocket[$CurrentSocket] = TCPAccept($MainSocket)
    If $ConnectedSocket[$CurrentSocket] <> - 1 Then
        $CurrentSocket = SocketSearch()
    EndIf
    $Track = 0
    For $Track = 0 To $MaxConnection Step 1
        If $ConnectedSocket[$Track] <> - 1 Then
            $Data = TCPRecv($ConnectedSocket[$Track], $MaxLength)
            If $Data = "~bye" Then
                TCPCloseSocket($ConnectedSocket[$Track])
                $ConnectedSocket[$Track] = -1
                $CurrentSocket = SocketSearch()
            ElseIf StringInStr($Data, "~send") >= 1 Then
                $Track = 0
                For $Track = 0 To $MaxConnection Step 1
                    If $ConnectedSocket[$Track] <> - 1 Then TCPCloseSocket($ConnectedSocket[$Track])
                    $ConnectedSocket[$Track] = -1
                    $CurrentSocket = 0
                Next
                TCPCloseSocket($MainSocket)
                TCPShutdown()
                $MainSocket = TCPSendTemp($Data)
            ElseIf $Data <> "" Then
            ; You received data.
                MsgBox(0, "Received Data", $Data)
            EndIf
        EndIf
    Next
WEnd
Func TCPSendTemp($DataString)
    TCPStartup()
; Syntax ~send-ip-port-data
    Local $Array = StringSplit($DataString, "-")
    Local $TempSocket = TCPConnect($Array[1], $Array[2])
    TCPSend($TempSocket, $Array[3])
    TCPCloseSocket($TempSocket)
    TCPShutdown()
    $MainSocket = TCPStartServer($Port, $MaxConc)
    Return $MainSocket
EndFunc  ;==>TCPSendTemp
Func TCPStartServer($Port, $MaxConnect = 1)
    Local $Socket
    $Socket = TCPStartup()
    Select
        Case $Socket = 0
            SetError(@error)
            Return -1
    EndSelect
    $Socket = TCPListen(@IPAddress1, $Port, $MaxConnect)
    Select
        Case $Socket = -1
            SetError(@error)
            Return 0
    EndSelect
    SetError(0)
    Return $Socket
EndFunc  ;==>TCPStartServer
Func SocketSearch()
    Local $Track = 0
    For $Track = 0 To $MaxConnection Step 1
        If $ConnectedSocket[$Track] = -1 Then
            Return $Track
        Else
        ; Socket In Use
        EndIf
    Next
EndFunc  ;==>SocketSearch

This is just presuming I am understanding and interpreting you correctly.

Best Wishes

- AutoIt Smith

Share this post


Link to post
Share on other sites

I would use command line switches so instead of having 2 different exe's just launch the same exe with a different switch.

If $cmdline[0] = 0 Then
;First instance of code
;do some stuff
;launch new process
Run(@ComSpec & " /C " & @AutoItExe & " /thread2")

ElseIf $cmdline[1] = "/thread2" Then
;do stuff in thread 2
;yah go me, i'm cool
;i want 3 threads though...
Run(@ComSpec & " /C " & @AutoItExe & " /thread3")

ElseIf $cmdline[1] = "/thread3" Then
;wow i'm so the man, i have 3 processes!

EndIf

Somthing like that :o

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Or...

AdlibEnable("Adlib", 1000)
Dim $Foo[100]; maximum number of child processes

$NewTempFile = Int (Random () * 10000)  & ".Au3"
FileWriteLine ($NewTempFile,'MsgBox (0,@scriptname,"I am the new file 1 running and the main program is still doing its own thing", 2)')
FileWriteLine ($NewTempFile,'ConsoleWrite ( "Info I want to send back to main application from child Number 1") ')

$Foo[1] = Run(@AutoItExe & ' /AutoIt3ExecuteScript ' & $NewTempFile,@scriptdir,  @SW_show, 7)


$NewTempFile = Int (Random () * 10000)  & ".Au3"
FileWriteLine ($NewTempFile,'MsgBox (0,@scriptname,"I am the new file 2 running and the main program is still doing its own thing", 2)')
FileWriteLine ($NewTempFile,'ConsoleWrite ( "Info I want to send back to main application from child Number 2") ')

$Foo[2] = Run(@AutoItExe & ' /AutoIt3ExecuteScript ' & $NewTempFile,@scriptdir,  @SW_show, 7)

    For $i = 1 to 5
    MsgBox (0,"Main", "I am the main program",2)
    Next


Func Adlib ()
    For $i = 1 to Ubound ($Foo) - 1 
        If @error then exitloop
    $line = StdoutRead($foo[$i],"",true)
    If $Line <> 0 then 
        $line = StdoutRead($foo[$i])
    MsgBox(0, "STDOUT read:", $line)
EndIf
Next
EndFunc
Edited by ChrisL

Share this post


Link to post
Share on other sites

ChrisL, I've run with your idea, you're credited here. It's basically a UDF library that handles Coroutines, kind of like LUA does. There's a couple examples in that thread if you're interested.


[u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia

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