Sign in to follow this  
Followers 0
JRowe

SOLVED: Help with CoProc, trying to send/read values from multiple processes

2 posts in this topic

#1 ·  Posted (edited)

I'm trying to figure out how data is passed between the processes, using the CoProc UDF. I want to have 3 or more processes. Spawning them is easy, I just treat each like it's own separate script. I can't figure out how to send data between them. I'd like to learn how to have CoProc 1 and CoProc 2 communicate with the Main Process, both ways.

Here's what I have so far:

#NoTrayIcon
#include <GUIConstants.au3>
#include "coproc.au3"

#region Main Process
$CoProc1Process = _CoProc ("CoProc1")
$CoProc2Process = _CoProc ("CoProc2")
$Form1 = GUICreate("Main Process", 300, 100, 350, 125)
$Label1 = GUICtrlCreateLabel("5", 10, 40, 148, 52)
$CoProc1Label = GUICtrlCreateLabel("CoProc1:", 110, 40, 148, 52)
$CoProc2Label = GUICtrlCreateLabel("CoProc2:", 210, 40, 148, 52)
$i1 = 5

GUISetState(@SW_SHOW)
While 1
    $msg = GUIGetMsg()

    Select
    Case $msg = $GUI_EVENT_CLOSE Or Not ProcessExists($CoProc1Process) Or Not ProcessExists($CoProc2Process)
            ExitLoop
        Case Else
    ;;;;;;;
        EndSelect
        GUICtrlSetData($Label1, "Main Process:" & $i1)
        $i1 = $i1 + 5
        Sleep(500)

WEnd
ProcessClose($CoProc1Process)
ProcessClose($CoProc2Process)
Exit
#endregion

#region CoProc1
Func CoProc1()
$Form2 = GUICreate("CoProc1", 100, 100, 350, 260)
$Label3 = GUICtrlCreateLabel("1", 49, 49, 148, 52)
$i2=1
    GUISetState(@SW_SHOW)
    While 1
    GUICtrlSetData($Label3, $i2)
        $i2 = $i2 + 1
        Sleep(500)
    WEnd
    Exit
EndFunc
#endregion


#region CoProc2
Func CoProc2()
$Form3 = GUICreate("CoProc2", 100, 100, 560, 260)
$Label4 = GUICtrlCreateLabel("1", 49, 49, 148, 52)
$i3 = 2
    GUISetState(@SW_SHOW)
    While 1
        GUICtrlSetData($Label4, $i3)
        $i3 = $i3 + 2
        Sleep(500)
    WEnd
    Exit
EndFunc
#endregion

This starts a single process, which then spawns two CoProcesses. Each launches a little GUI, and then updates a label on the gui every .5 seconds.

I'd like to be able to send the data from the two CoProcesses to the main process, and have it update the two additional labels.

There are several options in the CoProc documentation, but I can't understand any of them. They seem to be setting/getting SuperGlobal variables, or using an event receiver.

Here's the updated CoProc.au3 :CoProc.au3

There were a few syntax updates that needed to be made; just changing long_ptr to long*. Everything else is as the original.

*************

The solution is relatively simple: You need a message queue and a parser. Use _CoProcSend () to send a message from a CoProc to the main process. Parse the message to determine where it was sent from and what the content is. Perform an action according to the result.

Easy!

Edited by Jrowe

Share this post


Link to post
Share on other sites

One potential solution that I've just discovered is a message parser.

I think that this has to be done in any case, so here's the code: CoProc1 and 2 both increment a variable every half second. The main process increments every second. The CoProcesses send a message to the main process, prefixed with CP1 or CP2. The message receiver function checks the prefix, and then performs a label update based on the message received.

So far, so good :)

#NoTrayIcon

#include <GUIConstants.au3>

#include "coproc.au3"

#region Main Process

$CoProc1Process = _CoProc ("CoProc1")

$CoProc2Process = _CoProc ("CoProc2")

$Form1 = GUICreate("Main Process", 300, 100, 350, 125)

$Label1 = GUICtrlCreateLabel("5", 10, 40, 148, 52)

$CoProc1Label = GUICtrlCreateLabel("CoProc1:", 110, 40, 148, 52)

$CoProc2Label = GUICtrlCreateLabel("CoProc2:", 210, 40, 148, 52)

$i1 = 5

GUISetState(@SW_SHOW)

_CoProcReciver ("CoProcMessageReceiver")

While 1

$msg = GUIGetMsg()

Select

Case $msg = $GUI_EVENT_CLOSE Or Not ProcessExists($CoProc1Process) Or Not ProcessExists($CoProc2Process)

ExitLoop

Case Else

;;;;;;;

EndSelect

GUICtrlSetData($Label1, "Main Process:" & $i1)

$i1 = $i1 + 5

Sleep(1000)

WEnd

ProcessClose($CoProc1Process)

ProcessClose($CoProc2Process)

Exit

Func CoProcMessageReceiver($vParameter)

$ParsedMessage = StringLeft( $vParameter, 3 )

if $ParsedMessage = "CP1" Then

GUICtrlSetData($CoProc1Label, "CoProc1:" & StringTrimLeft ( $vParameter, 3 ))

ElseIf $ParsedMessage = "CP2" Then

GUICtrlSetData($CoProc2Label, "CoProc2:" & StringTrimLeft ( $vParameter, 3 ))

EndIf

EndFunc

#endregion

#region CoProc1

Func CoProc1()

$Form2 = GUICreate("CoProc1", 100, 100, 350, 260)

$Label3 = GUICtrlCreateLabel("1", 49, 49, 148, 52)

$i2=1

GUISetState(@SW_SHOW)

While 1

GUICtrlSetData($Label3, $i2)

_CoProcSend ($gi_CoProcParent, "CP1" & $i2)

$i2 = $i2 + 1

Sleep(500)

WEnd

Exit

EndFunc

#endregion

#region CoProc2

Func CoProc2()

$Form3 = GUICreate("CoProc2", 100, 100, 560, 260)

$Label4 = GUICtrlCreateLabel("1", 49, 49, 148, 52)

$i3 = 2

GUISetState(@SW_SHOW)

While 1

GUICtrlSetData($Label4, $i3)

_CoProcSend ($gi_CoProcParent, "CP2" & $i3)

$i3 = $i3 + 2

Sleep(550)

WEnd

Exit

EndFunc

#endregion

So I'll need to figure out timing issues with the message queue, because if you set all three sleeps to 500ms, the program will hang a bit. Otherwise, this works nicely :)

If there's a better solution, please let me know.

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