Coroutine Multithreading Udf Library

39 posts in this topic

neogia 0

Universalist

Active Members

0

269 posts

#1 ·
Posted 22 Mar 2006
(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
;===============================================================================

Share this post

Link to post

Share on other sites

neogia 0

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

b8bboi 0

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

neogia 0

Universalist

Active Members

0

269 posts

#11 ·
Posted 26 May 2006

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.

Share this post

Link to post

Share on other sites

ABANDONEDACC 0

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 20 Jul 2006 by darkthorn

Share this post

Link to post

Share on other sites

ABANDONEDACC 0

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

Share this post

Link to post

Share on other sites

ABANDONEDACC 0

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

Edited 20 Jul 2006 by darkthorn

Share this post

Link to post

Share on other sites

neogia 0

Universalist

Active Members

0

269 posts

#19 ·
Posted 20 Jul 2006

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.