Sign in to follow this  
Followers 0

Coroutine Multithreading Udf Library

39 posts in this topic

Posted (edited)

There were alot of requests for this type of library, and I found a thread that had a great idea for it (can be found here credit: ChrisL). So I decided to flesh it out, and I think it turned out well. It is in its beginning version, so forgive me if it's buggy.

Instead of putting lengthy instructions here, I've just included a couple of examples. I will be updating with full instructions later, and more examples. I've also included a helper script, FormatCoCreate.au3. When you run this script, it simply waits for the hotkey "Ctrl+Shift+C". What you do is highlight the function you want to turn into a thread, then press the hotkey, and it puts it into the correct format for you.

A couple of things to note: Variables can be passed in any form except variables of type Object, and DllStruct. Arrays consisting of up to 4 dimensions can be passed, as well as arrays nested in the elements of other arrays. The example scripts display this well. One other thing, the special delimiter, "$[" cannot be included anywhere in your threaded function. "$" and "[" can exist just fine, but not together.

I hope this is useful, let me know what you think and if you have any questions or find any bugs post them in this thread.

Version: 1.0.4 Date: 7/19/06

;===============================================================================
;
; File: Coroutine.au3
; Description: UDF Library used for coroutine multithreading
; Version: 1.0.4
; Date: 7/19/06
; Author: Ben Brightwell
; Credit: ChrisL for the base idea of deploying files as child scripts. Topic
;           can be found here:
;           http://www.autoitscript.com/forum/index.php?showtopic=22048
;
;===============================================================================

;===============================================================================
#cs
    Changelog:
    
    7/19/06 (1.0.4) - Fixed bug where using the substring "func" anywhere in a
                        line of code caused it to be truncated. Now the only
                        limitation is that the substrings "func" and "endfunc"
                        cannot be found at the beginning of a line of code.
    
    4/25/06 (1.0.3) - Fixed bug with using variables that contained the word
                        "return"
                    - Fixed bug with StringLower()-ing every line of code
                        in coroutine script, now case is untouched
                    - Fixed the way _CoInclude() works so that included code
                        is placed at the top of the file instead of the bottom
                    - Fixed a bug with passing a simple string to the script
                        an extra dimension indicator was present
    
    4/15/06 (1.0.2) - Truncated version number (Builds are irrelevant)
                    - Added support for exp[b][/b]ressions in the return statement
                        of a coroutine
                        
    3/23/06 (1.0.1.0) - Modified _CoCreate() to handle a function with no 
                            parameters
                      - Added "Core Function List" and "Miscellaneous Function 
                            List"
                      - Added this Changelog
                      - Changed _CoAddHelper() to _CoInclude()
                      - Fixed a bug in _CoInclude() where the last line of code
                            was not being read into the script file
#ce
;===============================================================================

;===============================================================================
#cs
    Core Function List:
    
    _CoCreate()
    Create a coroutine script which can be instanced by _CoStart()
    
    _CoInclude()
    Include helper/wrapper functions to compliment the main body created by
        _CoCreate()
    
    _CoStart()
    Create an instance of a threaded function as created by _CoCreate()
    
    _CoYield()
    NOTE: Only to be used in coroutine scripts
        Pauses the coroutine and yields a value to the main script, returns
        any value passed by the corresponding call to _CoResume()
    
    _CoStatus()
    Returns the status of a coroutine
    
    _CoSend()
    Sends a variable into a child script
    
    _CoResume()
    Unpauses a coroutine, optionally sends a value back to the yielded
        coroutine
    
    _CoGetReturn()
    Retrieves a variable returned by a coroutine
    
    _CoKill()
    Closes a coroutine
    
    _CoCleanup()
    Closes all running coroutines, and deletes their respective temporary script
        files
    
    _CoChangeWorkingDir
    Changes the working directory for storing the temporary script files.
        NOTE: Default is @TempDir
    
    Miscellaneous Function List:
        NOTE: These functions are meant to be called internally by Coroutine.au3
    
    _PackVarToStr()
    Packs a variable into a string for transmission between scripts.
    
    _UnpackStrToVar()
    Unpacks a packed variable-string into its original structure, whether it be
        a string or array.
    
    _RandomFileName()
    Generates a random unused filename for use with _CoCreate()
#ce
;===============================================================================

Edit: v1.0.4 was released(7/19/06)

Edit: uploaded wrong Coroutine.zip earlier, correct version is uploaded at 2:44am CST

Edit: v1.0.3 was released(4/25/06) (Downloads: 123)

Edit: v1.0.2 was released(4/15/06) (Downloads: 24)

Edit: Truncated post was fixed/ v1.0.1.0 was released(3/23/06) (Downloads: 39)

FormatCoCreate.au3

Coroutine.au3

Edited by neogia

Share this post


Link to post
Share on other sites



Posted

Very interesting...

Multi-threading is what I am looking for...

OffTopic: note that there is a post limit and your source was cut off

#)

Share this post


Link to post
Share on other sites

Posted

Very interesting...

Multi-threading is what I am looking for...

OffTopic: note that there is a post limit and your source was cut off

#)

Well, I'm glad it might be of use to you. Let me know if you need some help with it.

OffTopic: Thanks for that, I did think my post was rather short, I guess I'll just change it to contain the function names.

Share this post


Link to post
Share on other sites

Posted

Released Version: 1.0.1.0

Share this post


Link to post
Share on other sites

Posted

Released Version: 1.0.2

Added support for returning expressions from a coroutine. (Didn't realize AutoIt handled that automatically, I thought I would have to create my own lexer.)

Share this post


Link to post
Share on other sites

Posted (edited)

Released Version: 1.0.3

4/25/06 (1.0.3) - Fixed bug with using variable names that contained the word "return"

- Fixed bug with StringLower()-ing every line of code in coroutine script, now case is untouched

- Fixed the way _CoInclude() works so that included code is placed at the top of the file instead of the bottom

- Fixed a bug with passing a simple string to the script an extra dimension indicator was present

Edited by neogia

Share this post


Link to post
Share on other sites

Posted

This is the first time i have actually looked at this in detail and it works perfectly! Well done

Share this post


Link to post
Share on other sites

Posted

Awesome, I was looking for something like this.

Share this post


Link to post
Share on other sites

Posted

This is the first time i have actually looked at this in detail and it works perfectly! Well done

Awesome, I was looking for something like this.

Thanks for the compliments. I'm actually currently working on a large project for work that solves a major problem of mine. I was previously using TCP/IP to communicate between my scripts, but they had to be separately compiled, and reloaded to the server... blah blah blah. One of the major problems was that you had to disable any firewalls to allow the TCP/IP to function. Solved with Std** and Console** communication between scripts!

Share this post


Link to post
Share on other sites

Posted

Ben, a couple of questions.

1. Can a coroutine access global variables in the parent thread or do you have to use _CoSend()?

2. If the parent process is killed forcefully, ie. via Task Manager, is the coroutine process killed as well?

Share this post


Link to post
Share on other sites

Posted

1. Can a coroutine access global variables in the parent thread or do you have to use _CoSend()?

Good question. No, global variables are only global in either the main thread or in the child thread. You either have to a)use _CoSend() to dynamically send a value to the child thread or b)supply the variable in the argument(s) in the call to _CoStart(function, "$arg1,$arg2,$argN"). NOTE: when using _CoSend(), the child script has to "receive" or be "looking" for the variable to be sent.

2. If the parent process is killed forcefully, ie. via Task Manager, is the coroutine process killed as well?

The short answer no. I can affect this change rather simply though, and now that you mention it, I think I will. It will be in the next release.

Thanks for all your input, let me know if you need any further help.

Share this post


Link to post
Share on other sites

Posted (edited)

a question :

$_StartMuliThread = _CoCreate(  'Func Count($return)|'& _
                                '#NoTrayIcon|'& _
                                '   Return msgbox( 0, "BLUB"&$return , "number : " & $return  )|'& _
                                'EndFunc')
Dim $MBoX[5],$_Run[5]
For $i = 1 To 4
    $MBoX[$i]= _CoStart($_StartMuliThread, '$_Run['&$i&']')
Next
Local $c_Count = 0
While 1
    $c_Count += 1
    
        If _CoStatus($MBoX[$c_Count]) == "returned" Then
            $MBoX[$c_Count]= _CoStart($_StartMuliThread, '$_Run['&$c_Count&']')
            WinMove( "BLUB$_Run["&$c_Count&"]" , "" , Random( 0 , @DesktopWidth-100 ) , Random( 0, @DesktopHeight-100) )
            ;_CoKill($MBoX[$c_Count])
        EndIf
    
    If $c_Count == 4 Then $c_Count = 0
WEnd

this wont work as i want it, i want that he creates endless messageboxes, and moves them random but it wont work :< pls help^^

Edited by Busti

Share this post


Link to post
Share on other sites

Posted (edited)

#include <Coroutine.au3>

$_StartMuliThread = _CoCreate(  'Func Count($return)|'& _
                                '#NoTrayIcon|'& _
                                '   Return msgbox( 0, "BLUB"&$return , "number : " & $return  )|'& _
                                'EndFunc')
Dim $MBoX[5],$_Run[5]
For $i = 1 To 4
    $MBoX[$i]= _CoStart($_StartMuliThread, '$_Run['&$i&']')
Next
Local $c_Count = 0
While 1
    $c_Count += 1
    
        If _CoStatus($MBoX[$c_Count]) == "returned" Then
            $MBoX[$c_Count]= _CoStart($_StartMuliThread, '$_Run['&$c_Count&']')
            WinWait("BLUB$_Run["&$c_Count&"]")
            WinMove( "BLUB$_Run["&$c_Count&"]" , "" , Random( 0 , @DesktopWidth-100 ) , Random( 0, @DesktopHeight-100) )
            ;_CoKill($MBoX[$c_Count])
        EndIf
    
    If $c_Count == 4 Then $c_Count = 0
WEnd
oÝ÷ Ù.­h§2Þq©eÁ«+zÛ«)àÓbrj{"µØm~)ݶ°whÁ*ë-i×^u¥¢f¢µ©ÝÜ(®Kwq©è¢¨"ëaȬ~Þvç¶*'jZn®,zÊâ[)ä[(§ÊjYB¡+Z®Ü"¶ýÓ~º}ýjjtߨýßÙz§)ݶ­
­j»n¶)bÍ뽩ZÑ/jWmzö¥¹«^jºÚÉé^éí±*2¢çh¦É-+ºw-Ú+ro'hx,¢g­)à)¶¬jëh×6
For $i = 1 To 4
    $temp = $_Run[$i]
    $MBoX[$i]= _CoStart($_StartMuliThread, '$temp')
Next

Edit: BTW, your _CoCreate() function looks much cleaner when it is edited like that. I might change FormatCoCreate() to stylize the function like that, thanks for the involuntary contribution. :)

Edited by neogia

Share this post


Link to post
Share on other sites

Posted

thank for help^^ i will test it and edit this post^^

no problem, i coult read it like this better :D

Share this post


Link to post
Share on other sites

Posted

New FormatCoCreate helper function released.

Changes

----------

- Now, the code you convert with the FormatCoCreate function keeps most of its readability and looks much nicer (thanks Busti).

Share this post


Link to post
Share on other sites

Posted (edited)

Update 7/20/06: Get v1.1.0 with a bunch of important patches.

Wow, congratulations on the most impressive script I've ever seen! I ran into trouble though. The function I am exporting (using the FormatCoCreate Helper) contains a While $RunFunction = 1 ... WEnd statement, and when exported only the WEnd remains (the While-line is removed).

I have several While-statements in the function, and the rest of them seem intact. Still, there is something wrong with your _CoCreate function as it seems to skip certain lines of the script. When I tried to change While $RunFunction = 1, to While 1, it was exported correctly, but then the EndFunc line was omitted instead. Weird indeed.

On a side note, CoInclude seems to work right, as any function included that way seems to be intact). Is it some kind of "error checking" on your part in the CoCreate function, that excludes certain lines? I'll be happy to show you the script over MSN / in PM so we can solve this bug, but I am not going to post it here since it's private.

Edited by darkthorn

Share this post


Link to post
Share on other sites

Posted (edited)

Update 7/20/06: Get v1.1.0 with a bunch of important patches.

Uhm... Further checking shows that setting "While $RunFunction = 1" to just "While 1" gets it included in the tempscript file. However, I got an error that there was a Func without matching EndFunc... so I checked the file, and noticed that the output file doesn't include full function definitions for YOUR functions! That's when I noticed, to my surprise, that the script just abruptly ended in the middle of the _UnpackStrToVar function. No EndFunc or anything, it ended right in the middle of the code!The file was 2KB. This was with "While 1" in my code.

When I tried it with "While $RunFunction = 1" I got the omitted "While" error again, but the output file contained more of your code, although still truncated and missing vital code. This file was now 5KB instead.

Due to the increased file size it doesn't seem like it could be AutoIt truncating the file due to size limitations, but rather that something in my imported function is throwing off your code completely, since your short, simple functions work fine (the included examples).

Edited by darkthorn

Share this post


Link to post
Share on other sites

Posted

I'm sending you a PM with the code that causes your script to break. Please don't post it on the forums, though.

I'm working on a fix for this right now, but if you'll look at line 183 of Coroutine.au3, you'll see the problem lies in the naming of your variable "$RunFunction" and it's truncating the line because it finds the substring "func". If you rename the variable to something that doesn't include "func", it should be a fine workaround until I release the next version. (ex: $RunFnction)

Thanks for your praise and for the very detailed bug submission. I'll have the fix out soon enough.

Share this post


Link to post
Share on other sites

Posted

Released Version: 1.0.4

7/19/06 (1.0.4) - Fixed bug where using the substring "func" anywhere in a

line of code caused it to be truncated. Now the only

limitation is that the substrings "func" and "endfunc"

cannot be found at the beginning of a line of code.

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