Home > Archive > Tcl > January 2008 > Stop / Pause a TCL script (using interrupts?)
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 |
Stop / Pause a TCL script (using interrupts?)
|
|
| bengoavs@gmail.com 2008-01-27, 8:27 am |
| Hi guys,
I need to have an option to stop and pause a tcl script from a GUI
application. Firstly thought of just killiing the process but need to
also support the pause option, and make things neat. How can it be
done ??
(The GUI is the one running the script if it helps)
| |
| Alexandre Ferrieux 2008-01-27, 7:52 pm |
| On Jan 27, 3:03=A0pm, bengo...@gmail.com wrote:
> Hi guys,
>
> I need to have an option to stop and pause a tcl script from a GUI
> application. Firstly thought of just killiing the process but need to
> also support the pause option, and make things neat. How can it be
> done ??
>
> (The GUI is the one running the script if it helps)
You already know 'kill -KILL' apparently, but it might help you to
know about 'kill -STOP' and 'kill -CONT', which mean respectively
'pause' and 'resume'. Beware not to deadlock on the paused child
though: by definition, if it is paused, it will not be sensitive to an
EOF on a pipe, and hence a [close $pipe], with the included waitpid(),
will block forever.
-Alex
| |
| suchenwi 2008-01-28, 9:02 am |
| On 27 Jan., 15:03, bengo...@gmail.com wrote:
> I need to have an option to stop and pause a tcl script from a GUI
> application. Firstly thought of just killiing the process but need to
> also support the pause option, and make things neat. How can it be
> done ??
Here's an alternative with a "Pause" checkbutton - the label counts up
seconds, except when "Pause" is activated:
#!/usr/bin/env tclsh
package require Tk
proc every {ms body} {uplevel \#0 $body; after $ms [info level 0]}
pack [checkbutton .pause -indicatoron 0 -text Pause -variable pause]
pack [label .l -textvariable foo]
set foo 0
every 1000 {if {!$pause} {incr foo}}
| |
| Bezoar 2008-01-28, 7:43 pm |
| On Jan 27, 8:03 am, bengo...@gmail.com wrote:
> Hi guys,
>
> I need to have an option to stop and pause a tcl script from a GUI
> application. Firstly thought of just killiing the process but need to
> also support the pause option, and make things neat. How can it be
> done ??
>
> (The GUI is the one running the script if it helps)
If you are on a Unix system then you can use signals but in this case
SIGUSR1 and SIGUSR2 by requiring the Tclx
extension. Heres as quick example . Run this code in one terminal
( change path to the tclsh shell at the top
to match your setup) then in another terminal use ps to determine the
pid. The send signals to it like I demonstrate
below. Note apparently in order to use vwait the way i do you must
register an after job otherwise you get the
infamous "Would wait forever" message.
----------------Script ---------------
#!/bin/sh
# the next line restarts using wish \
exec /opt/usr2/bin/tclsh8.5 "$0" ${1+"$@"}
lappend auto_path /opt/usr2/lib
if { [ catch {package require Tclx } err ] != 0 } {
puts stderr "Unable to find package Tclx ... adjust your
auto_path!";
}
# this is how to use signals in Tclx trap a signal(s) and call command
the signal is subst into %s befor eval
proc sigUser1 { signal } {
global interrupt
puts "[pid] got signal $signal"
if { [ expr $interrupt % 2 ] == 0 } {
incr interrupt
puts "....Pausing!"
}
}
proc sigUser2 { signal } {
global interrupt
puts -nonewline "[pid] got signal $signal"
if { [ expr $interrupt % 2 ] != 0 } {
incr interrupt
puts "....Resuming!"
}
}
proc do_nothing {} {
after 20000 do_nothing;
}
signal trap { SIGUSR1} [list sigUser1 %S ]
signal trap { SIGUSR2} [list sigUser2 %S ]
global interrupt
set interrupt 0
while { 1 } {
if { [expr $interrupt %2 ] != 0 } {
puts "Stopped"
flush stdout
set jobid [ after 20000 do_nothing ]
vwait interrupt
catch { after cancel $jobid }
} else {
after 400
}
puts "The time is now [clock format [clock seconds ] ]"
}
--------------------- end SCRIPT------------------------
The time is now Mon Jan 28 18:55:01 CST 2008
The time is now Mon Jan 28 18:55:01 CST 2008
The time is now Mon Jan 28 18:55:02 CST 2008
The time is now Mon Jan 28 18:55:02 CST 2008
The time is now Mon Jan 28 18:55:03 CST 2008
The time is now Mon Jan 28 18:55:03 CST 2008
The time is now Mon Jan 28 18:55:03 CST 2008
The time is now Mon Jan 28 18:55:04 CST 2008
The time is now Mon Jan 28 18:55:04 CST 2008
7008 got signal SIGUSR1
.....Pausing!
The time is now Mon Jan 28 18:55:05 CST 2008
Stopped
7008 got signal SIGUSR2....Resuming!
The time is now Mon Jan 28 18:55:13 CST 2008
The time is now Mon Jan 28 18:55:14 CST 2008
The time is now Mon Jan 28 18:55:14 CST 2008
The time is now Mon Jan 28 18:55:15 CST 2008
The time is now Mon Jan 28 18:55:15 CST 2008
| |
| Bezoar 2008-01-28, 7:43 pm |
| On Jan 27, 8:03 am, bengo...@gmail.com wrote:
> Hi guys,
>
> I need to have an option to stop and pause a tcl script from a GUI
> application. Firstly thought of just killiing the process but need to
> also support the pause option, and make things neat. How can it be
> done ??
>
> (The GUI is the one running the script if it helps)
Damn web interface submitted my last post before I finished. I do have
one minor correction
to the script. I noticed that is I did not keep making after event for
the vwait it would
bomb out with the "wait forever" error so here's the fix:
#!/bin/sh
# the next line restarts using wish \
exec /opt/usr2/bin/tclsh8.5 "$0" ${1+"$@"}
lappend auto_path /opt/usr2/lib
if { [ catch {package require Tclx } err ] != 0 } {
puts stderr "Unable to find package Tclx ... adjust your
auto_path!";
}
# this is how to use signals in Tclx trap a signal(s) and call command
the signal is subst into %s befor eval
proc sigUser1 { signal } {
global interrupt
puts "[pid] got signal $signal"
if { [ expr $interrupt % 2 ] == 0 } {
incr interrupt
puts "....Pausing!"
}
}
proc sigUser2 { signal } {
global interrupt
puts -nonewline "[pid] got signal $signal"
if { [ expr $interrupt % 2 ] != 0 } {
incr interrupt
puts "....Resuming!"
}
}
proc do_nothing { timeout } {
global job_id;
set job_id [after $timeout [list do_nothing $timeout ]]
}
signal trap { SIGUSR1} [list sigUser1 %S ]
signal trap { SIGUSR2} [list sigUser2 %S ]
global interrupt job_id
set interrupt 0
set job_id ""
while { 1 } {
if { [expr $interrupt %2 ] != 0 } {
puts "Stopped"
flush stdout
do_nothing 20000
vwait interrupt
catch { after cancel $job_id }
} else {
after 400
}
puts "The time is now [clock format [clock seconds ] ]"
}
|
|
|
|
|