1. I read a talk given by John Ousterhout (author of Tcl/Tk)
titled "Why Threads Are a Bad Idea (for most purposes)".
He suggests that events can be used in most cases with
a lot of benefits. I was wondering if there is any implementation
of events for normal user programs (other than the X server type
of programs) in any variant of UNIX. If so what is the API
and programming model ?
2. My other question is about implementations of TCP/IP in user space
using preemptive threads (perferably kernel supported threads) in
either UNIX or Mach. I'm specifically looking for performance numbers
such as throughput measured on reasonably high speed networks
(ex. 155Mbps ATM) and on reasonably fast platforms (Pentiums, Sparcs,
SGIs, Alphas etc.).
I will summarize and post whatever I learn. Please feel free to send mail
to go...@olympus.wustl.edu for further clarifications.
-gopal
I read a talk given by John Ousterhout (author of Tcl/Tk) titled "Why
Threads Are a Bad Idea (for most purposes)". He suggests that events can
be used in most cases with a lot of benefits.
I'd be most interested to hear a summary of his arguments, as I consider this
to be unadulterated nonsense. Especially the X11 method of using events.
Jan
One I can think of right off the bat is UNIX software signals. It is
possible to register a signal handler for any of the 32 (for SunOS 4.1.3)
signals four or five of which are user definable. This could provide an
event driven mechanism for programming.
-----------------------------------------------------------------------------
Marcello mvl...@barrow.uwaterloo.ca
j> I'd be most interested to hear a summary of his arguments, as I
j> consider this to be unadulterated nonsense. Especially the X11
j> method of using events.
Actually, what Ousterhout had to say was quite reasonable. If I
remember correctly (I saw an earlier version of his talk, made within
Sun last October or so), his points went something like this:
- For smallish applications that don't carry around a whole lot of
state, event-based programming is easier than using threads.
- Concurrent programming is just plain hard, and relatively few
programmers can do a good job at it. Ousterhout illustrated this
point by saying that maybe 95% of programmers could program in
Visual Basic, maybe 20% of those could do a reasonable job in C++,
and maybe 20% of that 20% could program competently using threads.
I should also point out that he didn't make the claim that threads are
always a bad choice, just that they introduce a lot of potentially
undesirable complexity; a lot of thought should be put into whether or
not to use them.
<b
--
Let us pray:
What a Great System. b...@eng.sun.com
Please Do Not Crash. b...@serpentine.com
^G^IP@P6 http://www.serpentine.com/~bos
In article <4khuck$l...@darkstar.UCSC.EDU> go...@ccrc.wustl.edu
(R.Gopalakrishnan) writes:
I read a talk given by John Ousterhout (author of Tcl/Tk) titled "Why
Threads Are a Bad Idea (for most purposes)". He suggests that events can
be used in most cases with a lot of benefits.
I'd be most interested to hear a summary of his arguments, as I consider this
to be unadulterated nonsense. Especially the X11 method of using events.
http://www.sunlabs.com/people/john.ousterhout.
I haven't looked at it yet.
mike gunter
It seems to me that one way of think about event based programming is to imaging
1 thread for each event, where the thread always runs to completion. If we make
the work of an event handler fine grained "enough" we don't have to worry about priority
or preemtion. E.g. loops can be handled by making an event at the end of the loop,
or making N events to represent the work of the loop. This thinking, I believe,
arrives at several interesting places that have been well visited in the realms of
data flow and real-time (Arvind, and Jeffay).
I think events without priority solves only part of the programming problem. But,
this is with my real-time hat on. OTH, I think there sits out there waiting for
the apporpriate tools an event based programming that solves both application
and "most" real-time programming type problems.
emil
In my opinion, are event driven programs and multi threaded programs,
the same. Each event handle can be implemented as thread, running in an
endless loop, waiting for an event message at the begin of the loop.
i.e.
TestProc () on event X
{
bla bla
}
is the same as
TestProc () thread
{
while (1) {
wait_for_event (X);
bla bla
}
}
Isn't it ?
--
Sebastian Schoenberg University of Cambridge, UK
Email: Sebastian....@cl.cam.ac.uk Dept. of Computer Science
>TestProc () on event X
>{
> bla bla
>}
>
>is the same as
>
>TestProc () thread
>{
> while (1) {
> wait_for_event (X);
> bla bla
> }
>}
>
>Isn't it ?
Only if "on event X" implies that TestProc is a monitor (i.e. only one
instance of TestProc can be invoked at a time). Perhaps this is the norm;
all event-based programming I've done has been of the event-message-to-port-
from-the-UI/OS style. The event-port handling process can invoke threads to
handle each event or any event that is "expensive" to handle, of course, which
is actually a quite straightforward and functional solution - so long as you
keep your thread accounting straight. Both methods ("pure" event-based and
thread-based (whether via a dispatch process or not)) can produce good
user-interface feedback, since hopefully the system is never busy and ignoring
input. Both also require care when modal UI/etc changes occur.
--
Randell Jesup, Scala US R&D, Ex-Commodore-Amiga Engineer class of '94
Randel...@scala.com
#include <std/disclaimer>
[event driven == thread based]
>TestProc () on event X
>{
> bla bla
>}
>
>is the same as
>
>TestProc () thread
>{
> while (1) {
> wait_for_event (X);
> bla bla
> }
>}
If this is correct, it only shows that an event-based programming
model can be constructed from a threads-based model, but not
necessarily the other way around. Given that one of John's big claims
from that talk is that the event-based model is simpler than the
threads-based model, this isn't that surprising. I doubt that one can
construct a general, preemtive, thread model from only an event model,
but I haven't thought it through. However, one of John's other big
claims is that most *uses* of the thread model can be better served by
an event-based model, and that's the interesting bit of the talk.
To return to the post, is this construction even correct?
It Depends. As another poster has pointed out, TestProc in the
event-driven sense had better be a monitor, otherwise the thread-based
implementation of the event model isn't right. However, as I read
John's slides, only one event handler can run at any given time,
*regardless* of the type of the event being handled. So, it would
appear that events are monitors.
But, what if the threads used to build the evnet model are preemptive?
If they are, you need to guarantee that each "event handler" runs to
completion; no handler may start until the currently running one
finishes. This is pretty simple to do: create a single mutex
Event_Lock, and recast your handlers as:
TestProc () thread
{
while (1) {
wait_for_event (X);
Acquire(Event_Lock,exclusive);
bla bla
Release(Event_Lock);
}
}
This removes several of the "why threads are hard" problems from
John's talk, namely synchronization (only one event runs at a time),
deadlock (all events run to completion), and so on. But, it
introduces one of the "Achieving good performance is hard" problems;
namely reducing concurrency through simple monitor-like locking
schemes. This is pretty much what he admits to near the end of the
slides; you are trading potential concurrency for simplicity in the
model. His argument is that this trade is advantageous more often
than many people think.
-brian
But given the utter simplicity of doing the same thing using threads (as you
illustrated), his conclusion doesn't seem justified. Thinking in thread
terms from the beginning makes it easier to make the *appropriate* trade-off
for your problem, without having to make a big switch in your mental model.
E.g., using several coarse-grained locks often isn't too much more complex,
and can win big.
-Miles
--
Miles Bader / mi...@gnu.ai.mit.edu / (617) 253-8568
No it doesn't. If several threads are waiting for the event, there's
(in general) no knowing which one is going to wake up first.
This is why some thread management systems include an atomic "wait for
this event and acquire the related lock"; that way, you know when you
wake up that _you're_ the one for whom the event fired, and you can
`clear' the event before you release the lock.
In general, there's no substitute for "being aware of when you might
be preempted"...
>[...] one of the "Achieving good performance is hard" problems;
>namely reducing concurrency through simple monitor-like locking
>schemes.
I.e., you trade simplicity for performance. Such is the world :-(
--
Robin (Campaign for Real Radio 3) Fairbairns r...@cl.cam.ac.uk
U of Cambridge Computer Lab, Pembroke St, Cambridge CB2 3QG, UK
Home page: http://www.cl.cam.ac.uk/users/rf/robin.html
In article <4mmdrj$1...@darkstar.UCSC.EDU> Brian Noble <bno...@cs.cmu.edu> writes:
If this is correct, it only shows that an event-based programming
model can be constructed from a threads-based model, but not
necessarily the other way around. Given that one of John's big claims
from that talk is that the event-based model is simpler than the
threads-based model, this isn't that surprising. I doubt that one can
construct a general, preemtive, thread model from only an event model,
but I haven't thought it through.
Given preemptive events, you can certainly construct a preemptive
threads environment. In fact, this is precisely what the operating
system does!
--
Jim Larson Jet Propulsion Laboratory
james.s...@jpl.nasa.gov #include <disclaimer.h>
I think you can do anything, and both models are really equivalent to each other.
You can write an event handler for a thread, tha looks like this
ThreadProc () event Start_ThreadProc
{
...
}
and somewhere you can start this with
SendEvent (Start_ThreadProc)
Is this one different to the following code
ThreadProc () thread
{
...
}
CreateThread (&ThreadProc);
>
> To return to the post, is this construction even correct?
>
> It Depends. As another poster has pointed out, TestProc in the
> event-driven sense had better be a monitor, otherwise the thread-based
> implementation of the event model isn't right. However, as I read
> John's slides, only one event handler can run at any given time,
^^^^^^^^ ^^^^^^
> *regardless* of the type of the event being handled. So, it would
> appear that events are monitors.
>
You can take every event-driven X-Windows program and you have this type
of code, and you don't need threads at all.
> But, what if the threads used to build the evnet model are preemptive?
> If they are, you need to guarantee that each "event handler" runs to
> completion; no handler may start until the currently running one
> finishes. This is pretty simple to do: create a single mutex
> Event_Lock, and recast your handlers as:
>
> TestProc () thread
> {
> while (1) {
> wait_for_event (X);
> Acquire(Event_Lock,exclusive);
> bla bla
> Release(Event_Lock);
> }
> }
>
No, that's not correct. If event handler are not preemptive, write your code,
using a 'SWITCH-CASE' statement in C. I think, about this kind of 'event handling',
we don't need to talk here.
> This removes several of the "why threads are hard" problems from
> John's talk, namely synchronization (only one event runs at a time),
> deadlock (all events run to completion), and so on. But, it
> introduces one of the "Achieving good performance is hard" problems;
> namely reducing concurrency through simple monitor-like locking
> schemes.
If you assume, event-proc and thread-proc are preemptive, you always have the
same to do for synchronization ...
> This is pretty much what he admits to near the end of the
> slides; you are trading potential concurrency for simplicity in the
> model. His argument is that this trade is advantageous more often
> than many people think.
As you've seen, threads and preemptive event handlers or programs with 'switch-case'
statement and non preemptive threads are equal to each other.
Sebastian
Not completely true. So it is not so easy :-).
You assume that 'bla bla' does not rely for completion to the
execution of other events. I guess it is most often the case if 'bla
bla' is doing only local computing (though, what about local
computation generating human computer interaction assumed to be
treated via events ? e.g common error dialog box in graphical
environments). It is not the common case if you are doing
distributed computation. In that case, your construction not only do
not prevent deadlock but is likely to generate it !
Consider two processes P1 and P2 and assume (to be consistent) that
messages or RPCs rely on events. Exercise the reception of the event
foo_call by P1 on the following example:
on P1:
foo () {
P2:bar();
}
foo2() {...}
> TestProc () thread
> {
> while (1) {
> wait_for_event (X);
> Acquire(Event_Lock,exclusive);
...
switch (X) {
case foo_call:
foo();
break;
case foo2_call:
foo2();
break;
}
...
> Release(Event_Lock);
> }
> }
on P2:
bar() {
P1:foo2()
}
> TestProc () thread
> {
> while (1) {
> wait_for_event (X);
> Acquire(Event_Lock,exclusive);
...
switch (X) {
case bar_call:
bar();
break;
}
...
> Release(Event_Lock);
> }
> }
>
Where the syntax Pi:function_name stands for a RPC, that is, a call to
the function function_name of process (server) Pi.
The event foo_call on process P1 execute a RPC, P2:bar(), to the
process P2 which in turn execute a RPC, P1:foo2(), on P1. As the event
treatment is frozen until the primary callee P1:foo() terminate, the
RPC P1:foo2() is queued (postponed) until the end of foo() which in
turn wait for P1:foo2() to complete. So the deadlock...
You face a very common deadlock pattern in distributed environments.
Concurrency in processes P1 would have prevent this, assuming that
there is no intrinsic resource race.
I have seen only the slides of the Ousterhout's talk and I do not
remember if distributed computation is treated as a special case.
--
georges Brun-Cottan
projet SOR, INRIA, B.P. 105 Rocquencourt, 78153 Le Chesnay Cedex, France.
Tel.: +33(1)39-63-54-26; Fax: +33(1)39-63-53-30;
<georges.b...@inria.fr> <http://prof.inria.fr/SOR/members/bruncott.html>