mwm@raven.relay.pa.dec.com (Mike (My Watch Has Windows) Meyer) (01/21/91)
In article <15750@sdcc6.ucsd.edu> djohnson@beowulf.ucsd.edu (Darin Johnson) writes: In article <42149@nigel.ee.udel.edu> new@ee.udel.edu (Darren New) writes: >Please tell me the difference between coroutines and lightweight >processes. I always thought that lightweight processes were two >'tasks' (i.e., independant program counters) sharing the same address >space. Lightweight processes (LWP) and co-routines (CR) have much in common, and some people blur the definition. Usually however, LWP's have the ability to context switch anywhere, like any process. CR's need only change context at IO, semaphores, and other special calls. CR's are a language construct, whereas LWP's are an OS construct. CR's require much less OS and machine support, but require more compiler support (co-routines share the same stack, global vars, etc). That pretty much sums it up, but I'd have put it a different way (one which I think highlights the critical differences): LWPs are scheduled by an external entity as a set of independent threads of control; CRs are a single thread that is passed between the CRs, with each CR deciding when to pass it to another CR, and which one gets it, and taking responsibility for saving whatever state it needs to restart. Actually, to avoid confusion, compiler support is not needed. CR's can be done in assembler without much fuss - device drivers often do this (usually when LWP's are unavailable). Further, if you're willing to do the appropriate magic, you can get LWPs without OS support specifically for them; but it's a lot of fuss. <mike -- Here's a song about absolutely nothing. Mike Meyer It's not about me, not about anyone else, mwm@pa.dec.com Not about love, not about being young. decwrl!mwm Not about anything else, either.
mwm@pa.dec.com (Mike (My Watch Has Windows) Meyer) (01/24/91)
In article <672@tnc.UUCP> m0154@tnc.UUCP (GUY GARNETT) writes:
This is my understanding of the "threads" or "lightweight processes"
issue; feel free to correct me if I am not up to date on the
terminology.
"threads", or "lightweight processes" are separate execution traces
which share the address spaces with one or more other processes,
regardless of the other processes weight. They were designed to allow
many of the simpler multitasking jobs (like re-drawing the screen or
recalculating the spreadsheet) to be done with lower overhead. They
are implemented in OS/2 and perhaps the Mach kernal.
The definition is right. The reason for creation (at least in the Unix
world) is wrong. There, they were built because Unix didn't have a way
off sharing data between distinct proceses (code has been shared
between processes running the same program for quite a while now).
"coroutines" are the individual processes in a cooperatinve
multitasking environment.
That's not the definition as I learned it. Coroutines are a
programming technic, wherein each coroutine calls the others as
subroutines. Instead of going to that subroutine and returning, it
goes to that subroutine, which eventually calls another coroutine.
The next time a coroutine is invoked after calling a corouinte, it
sees that coroutine returning. Unlike cooperative multitasking, all
coroutine calls are known at link time. Also, each coroutine specifies
which task starts next; this isn't left up to a scheduler somewhere.
As I understand it, the Amiga does not have "threads" or "lightweight
processes".
It depends on how you define the phrase :-). If you define it as a
task with low-context-switch overhead between another task, then all
Amiga tasks are lightweight.
Although all of the tasks and processes on the Amiga share an address
space, it is not intended that there be multiple execution traces
through the same code and data (with the well-defined exception of
certian operating system code). You *CAN* do it, but you do not get
the same benefits that threads get - the operating system overhead is
the same, and writing code to work this way adds its own overhead.
There is a CBM-supported way of creating such tasks. This looks a lot
like thread creation on OSF. In fact, doing a Posix-compliant threads
library for AmigaDOS shouldn't be to hard.
<mike
--
Cats will be cats and cats will be cool Mike Meyer
Cats can be callous and cats can be cruel mwm@pa.dec.com
Cats will be cats, remember this words! decwrl!mwm
Cats will be cats and cats eat birds.peter@sugar.hackercorp.com (Peter da Silva) (01/28/91)
In article <MWM.91Jan21105153@raven.relay.pa.dec.com> mwm@raven.relay.pa.dec.com (Mike (My Watch Has Windows) Meyer) writes: > [CRs take] responsibility for saving whatever state it needs to restart. What state is this? A coroutine's state is just its stack, and that's saved by the co-call. > Further, if you're willing to do the appropriate magic, you can get > LWPs without OS support specifically for them; but it's a lot of fuss. All you need is the ability to set up a stack context, and switch to another stack. Then add a round-robin scheduler. It's not a *lot* of fuss but it does tend to be machine, compiler, and even compiler revision dependent. -- Peter da Silva. `-_-' <peter@sugar.hackercorp.com>.
mwm@pa.dec.com (Mike (My Watch Has Windows) Meyer) (01/29/91)
In article <7641@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes: In article <MWM.91Jan21105153@raven.relay.pa.dec.com> mwm@raven.relay.pa.dec.com (Mike (My Watch Has Windows) Meyer) writes: > [CRs take] responsibility for saving whatever state it needs to restart. What state is this? A coroutine's state is just its stack, and that's saved by the co-call. Yes, there's very little state. But it's saved by the co-call, which is part of your program. You deleted the comparison to LWPs, where the state is saved by something outside of your program. > Further, if you're willing to do the appropriate magic, you can get > LWPs without OS support specifically for them; but it's a lot of fuss. All you need is the ability to set up a stack context, and switch to another stack. Then add a round-robin scheduler. It's not a *lot* of fuss but it does tend to be machine, compiler, and even compiler revision dependent. Ok, so it depends on what you consider a "lot". As an exercise, implementing co-routines isn't a lot of fuss. As part of another project where it's a distraction from solving the problem, it can be. <mike -- And then up spoke his own dear wife, Mike Meyer Never heard to speak so free. mwm@pa.dec.com "I'd rather a kiss from dead Matty's lips, decwrl!mwm Than you or your finery."
peter@sugar.hackercorp.com (Peter da Silva) (02/05/91)
In article <MWM.91Jan28115114@raven.pa.dec.com> mwm@pa.dec.com (Mike (My Watch Has Windows) Meyer) writes: > In article <7641@sugar.hackercorp.com> peter@sugar.hackercorp.com (Peter da Silva) writes: > What state is this? A coroutine's state is just its stack, and that's saved > by the co-call. > Yes, there's very little state. But it's saved by the co-call, which > is part of your program. Not at all, it might be a system call. In fact, in some realtime execs it *is* a system call, the core of the scheduler, and LWPs are built on top of co-call. It gives you more control of the task in a hard real-time situation. > You deleted the comparison to LWPs, where the > state is saved by something outside of your program. And, again, LWPs are implemented in many ways. I've implemented LWPs on top of coroutines to get a multithreaded Forth system running under RSX-11 and CP/M-80. It ran fine on the 8080, though when Karl added a clock interrupt and made the threads run pre-emptively we had to put a semaphore around all the BDOS and BIOS calls. > Ok, so it depends on what you consider a "lot". As an exercise, > implementing co-routines isn't a lot of fuss. As part of another > project where it's a distraction from solving the problem, it can be. True, but that's got nothing to do with whether or not there's any magic difference between LWPs and coroutines. There isn't. LWPs inherently have little more state than coroutines. The only difference is the existence of a routine to handle the scheduling... instead of "co-call(routine)" it's "co_call(self->next)". -- Peter da Silva. `-_-' <peter@sugar.hackercorp.com>.