Jump to content

Faking Multi Threading


ChrisL
 Share

Recommended Posts

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
Link to comment
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
        
    

        
    

    

    




    Link to comment
    
        
    
    
    

    
    Share on other sites
    

    
        
            

    

        
            

    

        
            

    

        
            

    

        
    


    
    More sharing options...

    


    

                    
                    
                    
                

                    

                    
                    





    

    

    
        
            
                


    
        
    

                
                
                    
                        

                    
                
            
        
        
            
                


themax90
            
            
                Posted 
                
            
        
    
    
        


themax90
            
        
        
            
                
                    


    
        
    

                    
                    
                        

                    
                
            
            
                Active Members
                
            
            
                
                    
                        
                            
                                
                            
                                 1.2k
                            
                                
                            
                        
                        
                    
                
            
            
                

    
    
        
A new beginning
    
    

            
        
    
    
        



    
        
            
                
                    
                    
                    
                    
                    
                
            
            
                
                    
                    
                        
                        
                            Share
                        
                        
                        
                        
                        
                            
                                
                            
                            
                            
                            
                            
                            
                        
                    
                
                
            
        

        
            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

Link to comment
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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

  • 4 weeks later...

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

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...