|
|
Subject: Dangerous update command
From: George Peter Staplin
Date: 12/1/2007 9:13:08 AM
Mats wrote:
> Dear all,
>
> In my Coccinella app I have code that transfer files back and forth
> and I have until now been using 'update' or 'update idletasks' to keep
> the GUI responsive, but was getting errors that the recursion limit
> was reached. This was nothing but the "Update considered harmful"
> http://wiki.tcl.tk/1255 problem, and I now understand how stupid it
> is. I just want to have some feedback how to use the trick 'after idle
> [list after 0 [list ...]]' in a situation with fileevents.
This is one problem with event-oriented programming with a single
process.
I've found that some bizarre things are needed at times in very active
I/O apps, such as disabling a fileevent, and then reenabling after some
action has been done, in order to avoid starving other event loop tasks.
You can also run into some serious problems if you use non-blocking I/O
when writing or using puts to a channel. There is no bound on the
pending write queue, so it can consume all available memory and
eventually crash, if the other end isn't reading fast enough. Thus, in
some apps it's safer to use:
fconfigure $chan -blocking 1
puts $chan $data
fconfigure $chan -blocking 0 ;#assuming non-blocking reading is desired
by default.
Using Tcl's pipe ([open |]) mechanism with a background worker that
feeds its results back is also often a solution that is overlooked. My
only complaint about Tcl's pipe is that it doesn't allow for an
arbitrary number of pipe channels. I've sometimes found it useful to
use 4 or more pipes when communicating with a background process.
George
|