Home > Archive > Tcl > August 2004 > problem with using the [::comm::comm send] command
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
problem with using the [::comm::comm send] command
|
|
|
| Hi all,
new day,new problem...
still working on Win NT, using Tcl/Tk 8.4.
I managed to run 2 processes: the main is my Gui in Tk, the second one
is a subprocess calling C dll.
I've opened a channel between those 2 to get data from the child
process, update my Gui and keep it alive during the process.
********************************
script1.tcl:
proc run {} {
source script2.tcl
}
button .b -text "initial" -command run
pack .b
wm title . "main"
**********************************
script2.tcl:
set msid [::comm::comm ids]; # gets the
connections
::comm::comm send $msid {eval .b configure -text "updated"}; #
updates GUI
*********************************
example of a run:
First push: msid = 1305
changes the text correctly
Second push: msid = 1305 1305 1305
error: "connect to remote failed; counldn't open socket..."
*************************************
I though I had created a second interpreter to run my script2.tcl by
calling "source script2.tcl", but it's not the case.
Does anyone know how to communicate between both thanks to the comm
package? Shall I open a pipeline with [open] command? if so, I'm also
stucked 'cause the [send] command doesn't work with NT and my Tk
version. That's why I've tried to use the comm package and so its
[send] command.
Lucy.
| |
| Bruce Hartweg 2004-08-19, 4:07 pm |
|
lucie wrote:
> Hi all,
>
> new day,new problem...
> still working on Win NT, using Tcl/Tk 8.4.
> I managed to run 2 processes: the main is my Gui in Tk, the second one
> is a subprocess calling C dll.
> I've opened a channel between those 2 to get data from the child
> process, update my Gui and keep it alive during the process.
>
>
> ********************************
> script1.tcl:
>
> proc run {} {
>
> source script2.tcl
> }
>
> button .b -text "initial" -command run
> pack .b
>
> wm title . "main"
>
>
> **********************************
> script2.tcl:
>
> set msid [::comm::comm ids]; # gets the
> connections
> ::comm::comm send $msid {eval .b configure -text "updated"}; #
> updates GUI
>
>
> *********************************
> example of a run:
>
> First push: msid = 1305
> changes the text correctly
>
> Second push: msid = 1305 1305 1305
>
> error: "connect to remote failed; counldn't open socket..."
> *************************************
>
>
> I though I had created a second interpreter to run my script2.tcl by
> calling "source script2.tcl", but it's not the case.
>
> Does anyone know how to communicate between both thanks to the comm
> package? Shall I open a pipeline with [open] command? if so, I'm also
> stucked 'cause the [send] command doesn't work with NT and my Tk
> version. That's why I've tried to use the comm package and so its
> [send] command.
>
the problem is you are NOT running 2 processes, you are only running ONE.
the source command just reads the command into your running program, you
want to use exec to actually run a seperate process (and use & so it runs
in the background.
in your case you are trying to send a message to yourself in the same prcoess
which kind of works the first time thru the only interp that comm knows about is
yourself so [comm:comm ids] gives back your own id (which you can also get with
comm:comm self). you use this and it works fine since you can opena socket with
yourself and so you send yourslef a message and you process it just fine. here
is where is gets messed up. each time comm make a connection, it learns about
who it is connected to and adds it to its list of known ids. in your self connect
case the "sender" part of the code adds who it connected to (which is itself)
and the "reciever" part of the code adds who connected to it (which again is itself)
so that is why the swecond time you get your own id 3 times once for self, once for
ourgoing connection too & once for incoming connection.
then you mistake in the code causes an error because you are taking the return of
a command that returns a list, and using it as s single item, which you were lucky
on the first time since there was only one & then get caught the second time around.
so even when you actually put this into 2 processes (by doing the [exec tclsh script2.tcl &])
your code as is will break even further, since now your script 2 will still be talking to himself,
and this time even the first command will fail because he will try to run it himself.
what you need to do is use [comm::comm self] in the first script to get your known
id and the pass that as a command line arg to the second script so he know what id
to send to.
The opther option since you are launching the second process yourself is the use
set fd ["|open tclsh scritp2" w+] to open a pipeline to the helper process and
the setup a filevent handler to get/write data from it, and code you second script
to read/write to stdin/stdout for communications. depending on what you need to do
this could be a little simpler/easier.
Bruce
| |
|
| Hi Bruce,
thank you for the very clear explanations. I was really ...
> what you need to do is use [comm::comm self] in the first script to get your known
> id and the pass that as a command line arg to the second script so he know what id
> to send to.
> The other option since you are launching the second process yourself is the use
> set fd ["|open tclsh scritp2" w+] to open a pipeline to the helper process and
> the setup a filevent handler to get/write data from it, and code you second script
> to read/write to stdin/stdout for communications. depending on what you need to do
> this could be a little simpler/easier.
>
> Bruce
I've done the first solution and passed the id of the first process as
an argument to the second one. I've tried to do a pipeline but the
problem is that the data from the stdout were all mixed (the
subprocess calls a dll that prints in the stdout) and I needed only a
part of those to update my widget in the main process. So I think it
is easier and more appropriated to use the first option and send my
useful data in the socket instead of using the stdout.
Thanks again!
Lucy.
| |
|
| Here is another question: I'm using a socket to run a subprocess and
I'd like to update an image in the main process thanks to data getting
from the child. But it seems that I have a problem to send some
variables to the main:
script1.tcl (main)
....
# creating a label to handle the image
set ima [label .ima -text "image" -image visu2D];
pack .ima
....
script2.tcl (child)
....
set masterId [lindex $argv 0]
set filename "image.bmp"
set visu2D [image create photo visu2D -format bmp -file $filename]
::comm::comm send $masterId {.ima configure -image visu2D }; #
updating the image in the main with new data in image.bmp
=> I'm getting the error: can't read visu2D, doesn't exist!!
Why is the variable "visu2D" unknwown although I declared it before?
Lucy.
| |
| Bruce Hartweg 2004-08-20, 3:59 pm |
|
lucie wrote:
> Here is another question: I'm using a socket to run a subprocess and
> I'd like to update an image in the main process thanks to data getting
> from the child. But it seems that I have a problem to send some
> variables to the main:
>
> script1.tcl (main)
>
> ...
> # creating a label to handle the image
> set ima [label .ima -text "image" -image visu2D];
> pack .ima
> ...
>
> script2.tcl (child)
>
> ...
> set masterId [lindex $argv 0]
> set filename "image.bmp"
> set visu2D [image create photo visu2D -format bmp -file $filename]
>
> ::comm::comm send $masterId {.ima configure -image visu2D }; #
> updating the image in the main with new data in image.bmp
>
> => I'm getting the error: can't read visu2D, doesn't exist!!
>
> Why is the variable "visu2D" unknwown although I declared it before?
> Lucy.
in your first processes, visu2D is the "name" of an image - not a variable.
to update this you have to do it *in this process*. you create a new
image in your suboprocess with the same name, and you also assign that
to a variable in your 2nd process.
the code as written above shouldn't give you that error - it won't do anything
because you are telling it to configure it's widget with the image named visu2D
which is already done, and the image hasn't changed. now, if what you
really have is something like send $masterid {.ima configure -image $visu2D}
you *will* get that error because the visu2D variable exists only in the second
process - not the first, but the command gets evaluated in the first. Even if
the fiorst defines the variable, it won't error but nothing will happen because
it doesn't magically change in process 1 just because it changed in process 2.
to reconfigure an image, all the image work must be done in the GUI process, so
to update it process 2 should send a command the rebuilds the image with the new
filename
send $masterId [list image create photo visu2D -format bmp -file $filename]
this causes process 1 to load the image, there is no need to have an image
loaded into process2. Also note that I used the list command to build the list
so that it is process 2 that expands the filename variable into the actual filename,
if you use braces {image .... $filename} then process one will try and find the
filename variable and you will error again.
Bruce
| |
|
| Bruce Hartweg <bruce-news@hartweg.us> wrote in message news:<8noVc.1$2Z2.0@dfw-service2.ext.ray.com>...
> lucie wrote:
>
>
> in your first processes, visu2D is the "name" of an image - not a variable.
> to update this you have to do it *in this process*. you create a new
> image in your suboprocess with the same name, and you also assign that
> to a variable in your 2nd process.
>
> the code as written above shouldn't give you that error - it won't do anything
> because you are telling it to configure it's widget with the image named visu2D
> which is already done, and the image hasn't changed. now, if what you
> really have is something like send $masterid {.ima configure -image $visu2D}
> you *will* get that error because the visu2D variable exists only in the second
> process - not the first, but the command gets evaluated in the first. Even if
> the fiorst defines the variable, it won't error but nothing will happen because
> it doesn't magically change in process 1 just because it changed in process 2.
> to reconfigure an image, all the image work must be done in the GUI process, so
> to update it process 2 should send a command the rebuilds the image with the new
> filename
>
> send $masterId [list image create photo visu2D -format bmp -file $filename]
>
> this causes process 1 to load the image, there is no need to have an image
> loaded into process2. Also note that I used the list command to build the list
> so that it is process 2 that expands the filename variable into the actual filename,
> if you use braces {image .... $filename} then process one will try and find the
> filename variable and you will error again.
>
> Bruce
ok, everything's clearer now. I've managed to display my images in the
GUI as I wanted to do.
Thank you so much Bruce,
Lucy.
|
|
|
|
|