Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can I Interrupt an "after" Command?

1 view
Skip to first unread message

Brian Ceccarelli

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Dear Tcl Gurus,

So far in my experience with Tcl (only a few days), I have discovered
than Tcl./Tk 8.1 is multi-threaded. While a procedure is running, the
user can hit a button and asynchronously set a variable. The procedure,
while it is running, can look at the newly modified variable and take
new action. I like this.

HOWEVER . . . . Then I put an "after 5000" command in my procedure. The
"after" command blocks the entire program, that is, every thread. Is
there an "after" variation which only blocks the thread the procedure is
running in? In POSIX terms, is there a pthread_sleep()?

Same question put differently: If I hit a button, the Tcl Event
Handler does not take action on the button until after the procedure's
"after" finishes. Can I interrupt a Tcl program while the program is in
the "after" time interval?

Brian

Scott Redman

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to

Brian Ceccarelli wrote:
>
> Dear Tcl Gurus,
>
> So far in my experience with Tcl (only a few days), I have discovered
> than Tcl./Tk 8.1 is multi-threaded. While a procedure is running, the
> user can hit a button and asynchronously set a variable. The procedure,
> while it is running, can look at the newly modified variable and take
> new action. I like this.

Actually, this is "event driven" programming. The Tcl Notifier is in
fact a separate thread, but ONLY if you built with --enable-threads
(or the equivalent on Windows) which is not the default.


> HOWEVER . . . . Then I put an "after 5000" command in my procedure. The
> "after" command blocks the entire program, that is, every thread. Is
> there an "after" variation which only blocks the thread the procedure is
> running in? In POSIX terms, is there a pthread_sleep()?

I think you want this:

after 5000 {set x 1}
vwait x

This will allow events to be handled (the GUI will be responsive) and
other events to occur (the vwait processes the event loop).

Bryan Oakley

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Brian Ceccarelli wrote:
>
> Dear Tcl Gurus,
>
> So far in my experience with Tcl (only a few days), I have discovered
> than Tcl./Tk 8.1 is multi-threaded. While a procedure is running, the
> user can hit a button and asynchronously set a variable. The procedure,
> while it is running, can look at the newly modified variable and take
> new action. I like this.

No, it is not multithreaded. It is event driven, which is different.

> HOWEVER . . . . Then I put an "after 5000" command in my procedure. The
> "after" command blocks the entire program, that is, every thread.

No, it blocks the _only_ thread.

> Is
> there an "after" variation which only blocks the thread the procedure is
> running in? In POSIX terms, is there a pthread_sleep()?

No.

>
> Same question put differently: If I hit a button, the Tcl Event
> Handler does not take action on the button until after the procedure's
> "after" finishes. Can I interrupt a Tcl program while the program is in
> the "after" time interval?

No. The theory is, if you do "after 5000" you are purposefully telling
the application to sleep for 5 seconds, which it is dutifully doing.

If you can describe why it is you think you need to use after in such a
manner, perhaps we can tell you a better way to accomplish the task. (if
I were a betting man, I'd bet what you are interested in is vwait).


--
Bryan Oakley mailto:oak...@channelpoint.com
ChannelPoint, Inc. http://purl.oclc.org/net/oakley

Alexandre Ferrieux

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to
Scott Redman wrote:

>
> Newbie says:
>
> > I have discovered than Tcl./Tk 8.1 is multi-threaded. While a
> > procedure is running, the user can hit a button and asynchronously
> > set a variable.
>
> Actually, this is "event driven" programming.

Eh-Eh... Expect to go through this a couple of times when 8.1 goes
final...

I am scared in advance by the drop of SNR of this group when this
explosive mix {threads, events, beginners} does burst,
(You guys had, by the way, been warned :^)

-Alex

Brian Ceccarelli

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to
By the ways guys, I am only a newbie to Tcl. As far as event-driven
multi-threaded programming, I am sort of an expert on the matter. I have
done a lot of this stuff using C++, Solaris, Posix and Sybase Open
Server. Tcl/Tk 8.1 is indeed multi-threaded. It's not a
single-threaded environment.

The Tcl/Tk Event-Notifier is active, yes. But while the 1st procedure is
executing in my Tcl program, I can press a GUI button and set a variable.
The 1st procedure is still running.. This, by definition, is
multi-threaded. If the event notifier waited for the first procedure to
finish, and then set my variable, then I would declare, "This is a
single-threaded program." But that is not the behavior.

The "after" command, blocks all threads. In the Solaris/POSIX world,
sleep() blocks all threads and pthread_sleep() blocks only a the current
thread. I am looking for the Tcl equivalent.

Brian Ceccarelli

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to

Scott Redman wrote:

> I think you want this:
>
> after 5000 {set x 1}
> vwait x

That's the ticket! Thanks MUY MUCHO!

My main Tcl/Tk Reference doesn't mention "vwait". However, my little
O'Reilly Pocket Reference mentions it.
Thanks for pointing it out.

Alexandre Ferrieux

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to

Does it work so cleanly ?
I mean, we all know the care that has to be taken when several event
sinks (like vwait) are started from different threads. Is the threading
part of 8.1 now so clean that all after/fileevents are properly demuxed
to their intended threads ? I'm not saying it's impossible; I'm just
asking for an official statement :).

Or did you mean *only from the main Tk thread* ?
In this case the caveat deserves a sticky one-line comment...

-Alex

Alexandre Ferrieux

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to
Brian Ceccarelli wrote:
>
> By the ways guys, I am only a newbie to Tcl. As far as event-driven
> multi-threaded programming, I am sort of an expert on the matter.


That was absolutely not obvious from your post.
Specifically, in no place was it stated that you had really made use of
the '[test]thread create' command. Instead, you said you had
'discovered' something which is mistakenly identified as MT by newbies
fairly often (the fact that most callbacks yield so quickly that Tcl
spend 99% of its time awaiting events).

> The "after" command, blocks all threads. In the Solaris/POSIX world,
> sleep() blocks all threads and pthread_sleep() blocks only a the
> current thread. I am looking for the Tcl equivalent.

Why on earth didn't you give this crystal-clear, unambiguous statement
of your problem in the first place ;-) ?

That is interesting. Two options now:

1) Create a new flavour of the unary [after] that uses
pthread_sleep.

2) Silently modify the existing unary [after] so that it always
does so. There is not much existing MT Tcl code to worry
about anyway (esp. given the catastrophic effect of today's
[after] you just pointed out !), and for single-threaded apps
it would change nothing.

Reactions ?

-Alex

Scott Redman

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to
> Does it work so cleanly ?
> I mean, we all know the care that has to be taken when several event
> sinks (like vwait) are started from different threads. Is the threading
> part of 8.1 now so clean that all after/fileevents are properly demuxed
> to their intended threads ? I'm not saying it's impossible; I'm just
> asking for an official statement :).

They are supposed to be.

-- Scott

Andreas Kupries

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to bcecc...@icagen.com

Brian Ceccarelli <bcecc...@icagen.com> writes:

> The "after" command, blocks all threads. In the Solaris/POSIX world,
> sleep() blocks all threads and pthread_sleep() blocks only a the current
> thread. I am looking for the Tcl equivalent.

This is something that should be posted to the scriptics bug database
IMHO, and it should be removed before 8.1 goes final.

http://www.scriptics.com/support/bugForm.html

--
Sincerely,
Andreas Kupries <a.ku...@westend.com>
<http://www.westend.com/~kupries/>
-------------------------------------------------------------------------------

Alexandre Ferrieux

unread,
Apr 22, 1999, 3:00:00 AM4/22/99
to

Excellent ! Now what about Tk ? I understand that all threads can make
widget-modification calls, but is there more than one thread that can
vwait on GUI events ? If not, what happens if a side-thread calls a
modal dialog like tk_getOpenFile ? If yes, by what magic are the GUI
event demuxed ?

-Alex

Donal K. Fellows

unread,
Apr 22, 1999, 3:00:00 AM4/22/99
to
In article <371D0BB5...@channelpoint.com>,
Bryan Oakley <oak...@channelpoint.com> wrote:

> Brian Ceccarelli wrote:
>> Same question put differently: If I hit a button, the Tcl Event
>> Handler does not take action on the button until after the procedure's
>> "after" finishes. Can I interrupt a Tcl program while the program is in
>> the "after" time interval?
>
> No. The theory is, if you do "after 5000" you are purposefully telling
> the application to sleep for 5 seconds, which it is dutifully doing.

In fact you can't ever interrupt a Tcl program (in a way it can
notice; preemption by other threads/processes on your system is OK)
except when that program asks if anything wishes to interrupt it.
This is at the (philosophical) heart of why an interpreter can never
have more than one thread running in it.

> If you can describe why it is you think you need to use after in such a
> manner, perhaps we can tell you a better way to accomplish the task. (if
> I were a betting man, I'd bet what you are interested in is vwait).

One thing that many people miss is that the [after] command has two
uses:

* Synchronous. Blocks the thread for the number of milliseconds
specified. e.g.

puts stderr "Hello"
after 2000
puts stderr "Goodbye"
exit

* Asynchronous. Schedules a piece of code for execution after a
number of milliseconds have passed. This code will only be
executed in an "interrupt" point, and when it runs it runs
uninterruptably in the same manner as ordinary Tcl code. You can
do some really neat stuff with this, including non-blocking
delays, (sort-of) continuations, and many other things I can't
think of at the moment. e.g.

after 2000 {set forever "has arrived"}
proc count n {puts $n; after 200 "count [incr n]"}
count 0
vwait forever
exit

Note that you can also prevent something scheduled with after from
happening if you have access to the after i.d. and this is useful
for some really quite sophisticated stuff. I don't feel like
doing a good example for it at the moment though... :^)

As you can see, understanding [after] is an interesting challenge.

Donal.
--
Donal K. Fellows http://www.cs.man.ac.uk/~fellowsd/ fell...@cs.man.ac.uk
-- The small advantage of not having California being part of my country would
be overweighed by having California as a heavily-armed rabid weasel on our
borders. -- David Parsons <o r c @ p e l l . p o r t l a n d . o r . u s>

0 new messages