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

Why doesn't OS/2 have fork()?

29 views
Skip to first unread message

Jim Brooks

unread,
Jan 4, 1997, 3:00:00 AM1/4/97
to

Why doesn't OS/2 have fork() built into the kernel?
Cloning a process is a slick way to build a program
which can break itself into threads. Local thread data
can be accessed very quickly when fork() is used,
just call malloc(), and the same pointer can be used
in all threads.

BTW, does Win32 have fork()?

--

| | Jim Brooks
| _ | jbr...@swbell.net
______________|_(_)_|______________ PGP public key available
+|+ [ ( o ) ] +|+
* O[_]---[_]O *

Eddie McCreary

unread,
Jan 7, 1997, 3:00:00 AM1/7/97
to

>>>>> "JB" == Jim Brooks <jbr...@swbell.net> writes:

JB> Why doesn't OS/2 have fork() built into the kernel? Cloning a
JB> process is a slick way to build a program which can break itself
JB> into threads. Local thread data can be accessed very quickly
JB> when fork() is used, just call malloc(), and the same pointer
JB> can be used in all threads.

It's quick, but it doesn't make for efficient code. There's quite
a bit of overhead involved. You're much better of using real
threads.

JB> BTW, does Win32 have fork()?

Nope, although NT probably supports it under it's POSIX layer.

--
Eddie McCreary "Jumpin' through hyperspace ain't
mailto:fo...@neosoft.com like dustin' crops boy."
http://www.neosoft.com/~forge H. Solo

Paul Speed

unread,
Jan 7, 1997, 3:00:00 AM1/7/97
to

Jim Brooks (jbr...@swbell.net) wrote:
: Why doesn't OS/2 have fork() built into the kernel?
: Cloning a process is a slick way to build a program
: which can break itself into threads. Local thread data
: can be accessed very quickly when fork() is used,
: just call malloc(), and the same pointer can be used
: in all threads.

: BTW, does Win32 have fork()?

: --

Why go through the overhead of creating a new process to act like
a thread, when you can just create another thread? beginthread() will
start new threads so much more elgantly than fork() IMHO.
-Keys


: | | Jim Brooks

Stephen Drye

unread,
Jan 7, 1997, 3:00:00 AM1/7/97
to Jim Brooks

Jim Brooks wrote:
>
> Why doesn't OS/2 have fork() built into the kernel?
> Cloning a process is a slick way to build a program
> which can break itself into threads. Local thread data
> can be accessed very quickly when fork() is used,
> just call malloc(), and the same pointer can be used
> in all threads.
>
> BTW, does Win32 have fork()?

Jim, I highly recommend that you pick up a book on threads (I suggest
Threads Primer by Bil Lewis) or find the FAQ for
comp.programming.threads. You're mixing up multi-threading and
multi-processing (in the software, not hardware sense) here.

The answer to your question is neither OS/2 or Win32 have fork() per
se. They have something similar, but it is very rarely used in
comparison to the thread support available in both OSes. The things
that fork() was used commonly for under UNIX have similar solutions
using threads. The main benefit of threads is they are considerably
lighter than full processes, taking approximately 1/100 the time to
start up, and considerably less memory. Most UNIXen have POSIX threads
by now, or they will in their next releases.

So for example if you had a server daemon under UNIX using a pool of 5
processes, it is not unreasonable to have a single process with 0-50
threads doing the same job under OS/2 or Win32. You would only have the
threads running when they are needed, too, since they are so quick to
start. Each request tends to get its own thread, eliminating the code
needed for queueing of incoming requests.

The concept of thread local memory also exists in both OSes, and both
have picked up the concept of thread local heaps, too. The stack is
always thread local.

Threads are a different way of thinking, but well worth the time.

Stephen Drye
scd...@magma.ca

Chris Lawrence (Contra)

unread,
Jan 7, 1997, 3:00:00 AM1/7/97
to

Jim Brooks (jbr...@swbell.net) wrote:
: Why doesn't OS/2 have fork() built into the kernel?

Because the OS/2 process model doesn't really have a concept of
fork(). Its a significantly different process model from Unix.

: Cloning a process is a slick way to build a program


: which can break itself into threads. Local thread data
: can be accessed very quickly when fork() is used,
: just call malloc(), and the same pointer can be used
: in all threads.

Whoa. This is not true. The fork() call duplicates the entire data
and text segments. It does *NOT* give both processes access to shared
data segment. The best you get is access to attached shared memory.
fork() does _*NOT*_ create threads. It creates an entirely new
process which shares a very few, and very spicific set of
characteristics with its parent:

+ Real, effective, and saved user ID. +
+ Real, effective, and saved group ID.
+ List of supplementary group IDs (see getgroups(2)).
+ Process group. ID
+ Environment.
+ File descriptors.
+ Close-on-exec flags (see exec(2)).
+ Signal handling settings (SIG_DFL, SIG_IGN, address).
+ Signal mask (see sigvector(2)).
+ Profiling on/off status (see profil(2)).
+ Command name in the accounting record (see acct(4)).
+ Nice value (see nice(2)).
+ All attached shared memory segments (see shmop(2)).
+ Current working directory
+ Root directory (see chroot(2)).
+ File mode creation mask (see umask(2)).
+ File size limit (see ulimit(2)).
+ Real-time priority (see rtprio(2)).

Notice that data segment is not in there.

: BTW, does Win32 have fork()?

No.

Note however that there is a partial and very limited simulation of
fork() under the OS/2 EMX libraries.

--
J C Lawrence Internet: co...@ibm.net
---------------(*) Internet: claw...@cup.hp.com
...Honorary Member Clan McFUD -- Teamer's Avenging Monolith...

Thomas Vandahl

unread,
Jan 8, 1997, 3:00:00 AM1/8/97
to

In article <32CEEA...@swbell.net>, Jim Brooks <jbr...@swbell.net> writes:
|> Why doesn't OS/2 have fork() built into the kernel?
fork() is an old fashioned way to create processes. OS/2 uses a more
advanced method to manage processes and threads.
You would have to emulate fork() on this management system but you will
loose a lot of features of the OS/2 task manager.
|>
|> BTW, does Win32 have fork()?
I highly doubt it.
--
Thomas Vandahl [Team OS/2] Technical University of Ilmenau, Germany
Thomas....@E-Technik.TU-Ilmenau.DE http://www.rz.tu-ilmenau.de/~os2/


Tarjei T. Jensen

unread,
Jan 8, 1997, 3:00:00 AM1/8/97
to

Jim Brooks wrote:
>
> Why doesn't OS/2 have fork() built into the kernel?
> Cloning a process is a slick way to build a program
> which can break itself into threads. Local thread data
> can be accessed very quickly when fork() is used,
> just call malloc(), and the same pointer can be used
> in all threads.


There is major problems with the fork() model of doing things. It works
well for small processes, but for real applications it is a nightmare.
It eats memory, virtual and otherwise. That is why no other modern
operating system contains fork(). It is simply not very good.


Greetings,


--
// Tarjei T. Jensen
// tar...@online.no || voice +47 51 62 85 58
// Support you local rescue centre: GET LOST!

Will Rose

unread,
Jan 8, 1997, 3:00:00 AM1/8/97
to

Jim Brooks (jbr...@swbell.net) wrote:
: Why doesn't OS/2 have fork() built into the kernel?
: Cloning a process is a slick way to build a program
: which can break itself into threads. Local thread data
: can be accessed very quickly when fork() is used,
: just call malloc(), and the same pointer can be used
: in all threads.

Threads were developed specifically to avoid the overhead of the process
fork/exec model. If you want to execute another program, use DosExec.

: BTW, does Win32 have fork()?

No. It doesn't have kernel threads, either.

Will
c...@crash.cts.com


Matthew Denner

unread,
Jan 8, 1997, 3:00:00 AM1/8/97
to
Jim Brooks wrote:
> 
> Why doesn't OS/2 have fork() built into the kernel?


as far as i'm away 'fork()' is present in microsoft C 6.00 under OS/2.

> 
> BTW, does Win32 have fork()?
>
 
no and it's a real pain to get round.

Cheers,
Matt

------------------------------------------------------------------------
Matthew Denner               Senior Programmer @ Abbotsbury Software Ltd
ma...@wdi.co.uk                                      http://www.wdi.co.uk

         'prepare to be assimilated.  resistance is futile'
                                                   The Borg
------------------------------------------------------------------------
 

Simon Bowring

unread,
Jan 8, 1997, 3:00:00 AM1/8/97
to

Jim Brooks wrote:
>
> Why doesn't OS/2 have fork() built into the kernel?

Possibly because:

1) It's not UNIX! Possibly (I've no idea!) IBM OS's historically
don't have fork() ?

2) OS/2 has been multithreaded from day 1 (before it had a GUI,
1987/88-ish). Unix never used to have threads, so forking
was required to (and *developed* to) be an efficient method
of building multi-process (NOT threaded) programs. [Aside
Although forking and execing a *new* process, is not IMHO
an elegant way of running a "co-process"].

If you have threads, you don't need to have fork, you just
start a new thread.

I would have preferred OS/2 to have fork(), just to ease porting UNIX
s/w! Of course, they may be technical reasons (due to process-model
differences maybe?) why fork() would not be efficient under OS/2.

> Cloning a process is a slick way to build a program
> which can break itself into threads. Local thread data
> can be accessed very quickly when fork() is used,
> just call malloc(), and the same pointer can be used
> in all threads.

I'm not sure why you think forking is more efficient, slicker, easier
or better than starting a new thread! With threads you have access
to global data automatically, and thread-local data can be on the
threads' stacks or dynamically allocated.

> BTW, does Win32 have fork()?

Not as far as I know, but I've limited experience on Win, and
don't have any references handy.

Regards

Simon Bowring

Alfons Hoogervorst

unread,
Jan 8, 1997, 3:00:00 AM1/8/97
to

Lo Jim Brooks <jbr...@swbell.net>:

>BTW, does Win32 have fork()?

Sorry: no.

Bye.

-------------mailto:pro...@worldaccess.nl------------
Hoogervorst, Alfons; systems programmer,
word player avant la lettre
-------------------------------------------------------
One cast makes you long, and one cast makes you short
-------------------------------------------------------

John Currier

unread,
Jan 9, 1997, 3:00:00 AM1/9/97
to

Matthew Denner <ma...@wdi.co.uk> wrote:

>Jim Brooks wrote:
>>
>> Why doesn't OS/2 have fork() built into the kernel?
>

>as far as i'm away 'fork()' is present in microsoft C 6.00 under OS/2.

No. MSC 6 did *not* have fork().

John Currier john.c...@checksol.com
Software Development Engineer Check Solutions

#include <std.disclaimer>

Douglas A. Hamilton

unread,
Jan 9, 1997, 3:00:00 AM1/9/97
to

Simon Bowring <sim...@ibm.net> wrote in article <32D3FA...@ibm.net>...

> Jim Brooks wrote:
> >
> > Why doesn't OS/2 have fork() built into the kernel?

The real reason OS/2 didn't have a fork is because it was originally
designed to run (this was at IBM's insistence) on the 286, which did not
have paged virtual memory capabilities. Without the ability to share page
table entries between processes with copy-on-write faulting, the only way
to implement fork is by wholesale copying of the entire process address
space. That was okay in the early 70's on the original UNIX machines
(which also did not have paged virtual memory) but only because process
sizes were small. By the mid 80's, when OS/2 was designed, it was clear
that large memory and large processes would be a fact of life. Thus, fork
was omitted deliberately because the performance would have been
unacceptable.

I suppose the question might have been revisited when IBM developed OS/2
2.0, which did require the 386 or better, and which does use paged virtual
memory. But by then, the focus was on graphical applications with message
queues, leading to my comment below.

> > BTW, does Win32 have fork()?

Win32 does not have a fork either, even though it was designed from start
with the assumption of paged virtual memory and even though the underlying
kernel does support fork. (The kernel has to support it because the POSIX
requires it.) Having spoken with Mark Lucovsky (one of the architects and
key developers of the Win32 subsystem), the reason I'm told that Win32 does
not support fork is because there was a fundamental question about what to
do with the message queue. If you fork a graphical process, meaning you
produce an exact clone, what does that mean with respect to the message
queue? Do they now share it? Does that mean they fight over who gets the
next message?

Arguably, MS could have considered any of a number of possible solutions,
including the possibility that you get a whole new instance of the
graphical app on your desktop with its own (new) message queue. But, under
the pressure to get a product out, the choice was to punt and simply edict
that Win32 does not have fork. Some of the justification for this choice
was, as surmised, a general attitude that fork was architecturally less
attractive than threads anyway.

Regards,
Doug Hamilton KD1UJ hami...@bix.com Ph 508-440-8307 FAX 508-440-8308
Hamilton Laboratories, 21 Shadow Oak Drive, Sudbury, MA 01776-3165, USA


Dale Pontius

unread,
Jan 9, 1997, 3:00:00 AM1/9/97
to

In article <32d2f8c6...@news.worldaccess.nl>,
blade.run...@another.spam.bot (Alfons Hoogervorst) writes:
> Lo Jim Brooks <jbr...@swbell.net>:

>
>>BTW, does Win32 have fork()?
>
> Sorry: no.
>
fork() must not be very important, then.

Use threads.

Or if you need processes, use Exec. Most of the time, one child simply
does exec() after fork(), anyway. With higher overhead.

Dale Pontius
(NOT speaking for IBM)

Jay Elston

unread,
Jan 9, 1997, 3:00:00 AM1/9/97
to

Here's one way that I used fork() for a Unix application that
processed requests to generate reports. For performance reasons,
it didn't make any sense to handle more than one request at
a time. The "Request Server" had a main loop that looked like:

DO FOREVER
{
GetEvent
IF EventWasRequest THEN
SpoolRequest
ELSE IF ChildProcessDone THEN
PerformChildDoneCleanUp

IF !ProcessRunning && RequestsAreSpooled
THEN
GetNextRequest
ProcessRequest
}

ProcessRequest looked like:

ChildPID = fork();
if ( ChildPID == 0 )
{
PerformReportProcessing( ... );
exit();
}
else
{
MaintainChildInfo(ChildPID);
}

One advantage to this scheme was that any resources required by
the child process (report processing, which involved allocating lots
and lots of memory) got returned to the O/S when the child process
exited. Since Unix didn't have a way to _reduce_ the amount of memory
a process had allocated, without the fork(), followed by the exit()
of the child process, the Server has to carry around all the baggage
generated by the report processing.

The other advantage was the ability to run the processing in a
thread, which allows the Server to spool requests during the processing.

This allowed the workstation that was used to handle these requests
to be used (when it wasn't processing reports) for other uses. Back
in the days of slow and expensive disks and expensive memory this was an
important consideration.


Jim Brooks <jbr...@swbell.net> scratched in the sand in comp.os.os2.programmer.misc
: Why doesn't OS/2 have fork() built into the kernel?
: Cloning a process is a slick way to build a program


: which can break itself into threads. Local thread data
: can be accessed very quickly when fork() is used,
: just call malloc(), and the same pointer can be used
: in all threads.

: BTW, does Win32 have fork()?

: --

Chris Marriott

unread,
Jan 9, 1997, 3:00:00 AM1/9/97
to

In article <5b039v$i...@bogus.cts.com>, Will Rose <c...@cts.com> writes

>: BTW, does Win32 have fork()?
>
>No. It doesn't have kernel threads, either.

This is incorrect. Both Windows 95 and Windows NT support threads.

Chris

----------------------------------------------------------------
Chris Marriott, SkyMap Software, U.K. e-mail: ch...@skymap.com
Creators of fine astronomy software for Windows.
For full details, visit our web site at http://www.skymap.com


Andrew Gierth

unread,
Jan 9, 1997, 3:00:00 AM1/9/97
to

>>>>> "Tarjei" == Tarjei T Jensen <tar...@online.no> writes:

Tarjei> There is major problems with the fork() model of doing
Tarjei> things. It works well for small processes, but for real
Tarjei> applications it is a nightmare. It eats memory, virtual and
Tarjei> otherwise. That is why no other modern operating system
Tarjei> contains fork(). It is simply not very good.

The above is pure, unadulterated bullshit.

fork() on Unix satisfies its intended function perfectly, in a more
flexible fashion than the process-starting calls of most other OSs.
*However*, fork() is not necessarily the right solution for certain
classes of problems; threads provide a *design* alternative, not a
functional equivalent.

In the absence of fork(), design of certain classes of server process is
seriously constrained. In particular, servers where considerable work
needs to be done as initialisation, but where it is *not* desirable to
do work for different clients in the same process context, are quite
difficult to write cleanly, often resorting to shared memory in contexts
where it is not strictly necessary.

On the other hand, some other classes of servers are harder to implement
efficiently if fork() is available, but not threads.

--
Andrew Gierth (and...@microlise.co.uk)

"Ceterum censeo Microsoftam delendam esse" - Alain Knaff in nanam

Dale Pontius

unread,
Jan 9, 1997, 3:00:00 AM1/9/97
to

In article <uf7mlmm...@zen.microlise.co.uk>,
I'd say that clone() has them all beat. Set the parms right and you
get fork(), threads, nearly anything in between, and perhaps a few
beyond.

Andrew Gierth

unread,
Jan 9, 1997, 3:00:00 AM1/9/97
to

>>>>> "Thomas" == Thomas Vandahl <tho...@e-technik.tu-ilmenau.de> writes:

Thomas> fork() is an old fashioned way to create processes. OS/2 uses
Thomas> a more advanced method to manage processes and threads.

'Advanced'? Rubbish. OS/2's process management is nothing special, and
OS/2's only advantage when it comes to threads is simply that it has
had them since day 1.

Stefaan A. Eeckels

unread,
Jan 9, 1997, 3:00:00 AM1/9/97
to

In article <32D3FD...@online.no>,
"Tarjei T. Jensen" <tar...@online.no> writes:
> There is major problems with the fork() model of doing things. It works
> well for small processes, but for real applications it is a nightmare.
This is true *only* if you've got no copy-on-write and page table entry
sharing. On modern hardware, fork() can be very efficient.
> It eats memory, virtual and otherwise. That is why no other modern
> operating system contains fork(). It is simply not very good.
Mach is fairly modern and has fork().

IMHO, both models have their merits. A modern OS should have *both*
facilities; the DosExec approach is not an alternative to fork(), as
it doesn't give sufficient control over the 'child' process (it's like
Unix's "system()" subroutine).

As pointed out by Douglas Hamilton, the reason why there is no fork()
in Win32 is not because threads/DosExec are superior to threads/fork(),
but because of the message queue. This is what happens when you base
a design on a kludge to get MS-DOS to multi-task.

In any case, threads on NT are slower than forks on, say, Linux (on the
same hardware), because there is little hardware support for setting up
the stacks.

The simple fact remains that a good OS needs both threads *and* fork.

-- Stefaan
_____________________________________________________________________________
Stefaan A Eeckels (Stefaan...@ecc.lu)
"The nice thing about standards is that there are so many of
them to choose from." -- Andrew S. Tanenbaum
_____________________________________________________________________________

Peter Chapin

unread,
Jan 9, 1997, 3:00:00 AM1/9/97
to sbow...@mpc-data.co.uk

On Wed, 8 Jan 1997, Simon Bowring wrote:

> I would have preferred OS/2 to have fork(), just to ease porting UNIX
> s/w! Of course, they may be technical reasons (due to process-model
> differences maybe?) why fork() would not be efficient under OS/2.

The EMX library for OS/2 does, in fact, support fork(). It does so
precisely to ease the porting of Unix software to OS/2. I have no idea how
it was done, but it works.

*****************************************************************************
Peter http://twilight.vtc.vsc.edu/~pchapin
pch...@twilight.vtc.vsc.edu Paganism: Ancient beliefs in a modern world


Ilya Zakharevich

unread,
Jan 10, 1997, 3:00:00 AM1/10/97
to

[A complimentary Cc of this posting was sent to Peter Chapin
<pch...@twilight.vtc.vsc.edu>],
who wrote in article <Pine.OSF.3.95.970109...@twilight.vtc.vsc.edu>:

>
> On Wed, 8 Jan 1997, Simon Bowring wrote:
>
> > I would have preferred OS/2 to have fork(), just to ease porting UNIX
> > s/w! Of course, they may be technical reasons (due to process-model
> > differences maybe?) why fork() would not be efficient under OS/2.
>
> The EMX library for OS/2 does, in fact, support fork(). It does so
> precisely to ease the porting of Unix software to OS/2. I have no idea how
> it was done, but it works.

... up to some extend, and with _a lot_ of overhead.

While fork() is indeed handy for 0.1% of the programs (shells and
secure servers), it is just an obsolete thing for the remaining
99.9%. I did not try servers, but to recode a shell to use spawn() takes
at most a couple of hours (if the shell is coded well - I would not
like to do it for pdksh, say).

The only reason it is in EMX is to allow us - stupid guys - to make a
lousy port of a program in 10-15 minutes. Doing something better takes
more time.

Ilya


Will Rose

unread,
Jan 11, 1997, 3:00:00 AM1/11/97
to

Chris Marriott (ch...@chrism.demon.co.uk) wrote:
: In article <5b039v$i...@bogus.cts.com>, Will Rose <c...@cts.com> writes

: >: BTW, does Win32 have fork()?
: >
: >No. It doesn't have kernel threads, either.

: This is incorrect. Both Windows 95 and Windows NT support threads.

But Win 3.1, Win32, don't.

will
c...@crash.cts.com


Chris Marriott

unread,
Jan 11, 1997, 3:00:00 AM1/11/97
to

In article <5b3s55$j...@justus.ecc.lu>, "Stefaan A. Eeckels"
<Stefaan...@ecc.lu> writes

>In any case, threads on NT are slower than forks on, say, Linux (on the
>same hardware), because there is little hardware support for setting up
>the stacks.

Can you explain what you mean by this? It is definitely NOT true that
threads are less efficient than doing a "fork"; that's the whole point
of multithreading - the fact that a thread context switch is much faster
than a process context switch!

Stefaan A. Eeckels

unread,
Jan 11, 1997, 3:00:00 AM1/11/97
to

In article <WmBM1NAQ...@chrism.demon.co.uk>,

Chris Marriott <ch...@chrism.demon.co.uk> writes:
> In article <5b3s55$j...@justus.ecc.lu>, "Stefaan A. Eeckels"
> <Stefaan...@ecc.lu> writes
>>In any case, threads on NT are slower than forks on, say, Linux (on the
>>same hardware), because there is little hardware support for setting up
>>the stacks.
>
> Can you explain what you mean by this? It is definitely NOT true that
I was sloppy and I should have said:
Setting up a thread on NT is slower than executing a fork on Linux...

> threads are less efficient than doing a "fork"; that's the whole point
> of multithreading - the fact that a thread context switch is much faster
> than a process context switch!

Why? the overhead is caused by switching from the application ring to
the OS ring, and this happens both for a process and a thread switch.

Chris Marriott

unread,
Jan 12, 1997, 3:00:00 AM1/12/97
to

In article <5b6t5b$g...@bogus.cts.com>, Will Rose <c...@cts.com> writes

You appear to be confused in your terminology. "Win32" is the name of
the 32-bit Windows API. There are at least 4 different implementations
of this API:

- Windows NT
- Windows 95
- Windows CE
- Win32s on top of Windows 3.1.

The Win32 API supports threads, and NT, 95, and CE are all
multithreaded. Win32s is just a 32-bit "layer" on top of Windows 3.1
allowing it to run some 32-bit applications; it does NOT implement
threads for obvious reasons.

Regards,

Chris Marriott

unread,
Jan 13, 1997, 3:00:00 AM1/13/97
to

In article <5b8h15$q...@justus.ecc.lu>, "Stefaan A. Eeckels"
<Stefaan...@ecc.lu> writes

>> threads are less efficient than doing a "fork"; that's the whole point
>> of multithreading - the fact that a thread context switch is much faster
>> than a process context switch!
>Why? the overhead is caused by switching from the application ring to
>the OS ring, and this happens both for a process and a thread switch.
>

Because switching between threads within a single process simple
involves changing the registers and stack. A process context switch, on
the other hand, involves swapping the entire address space which is MUCH
more expensive. All threads share the same address space.

Kent Tong

unread,
Jan 14, 1997, 3:00:00 AM1/14/97
to

Chris Marriott <ch...@chrism.demon.co.uk> wrote:

>In article <5b8h15$q...@justus.ecc.lu>, "Stefaan A. Eeckels"
><Stefaan...@ecc.lu> writes
>>> threads are less efficient than doing a "fork"; that's the whole point
>>> of multithreading - the fact that a thread context switch is much faster
>>> than a process context switch!
>>Why? the overhead is caused by switching from the application ring to
>>the OS ring, and this happens both for a process and a thread switch.
>>
>
>Because switching between threads within a single process simple
>involves changing the registers and stack. A process context switch, on
>the other hand, involves swapping the entire address space which is MUCH
>more expensive. All threads share the same address space.

What do you mean by swapping the entire address space? Doesn't
it suffice to switch the current page table by setting a
single page table register?


---
Kent Tong
v3 is out!!!
Freeman Installer ==> http://www.netnet.net/users/freeman/

Stefaan A. Eeckels

unread,
Jan 14, 1997, 3:00:00 AM1/14/97
to

In article <olgzlJAZ...@chrism.demon.co.uk>,

Chris Marriott <ch...@chrism.demon.co.uk> writes:
>
> Because switching between threads within a single process simple
> involves changing the registers and stack. A process context switch, on
> the other hand, involves swapping the entire address space which is MUCH
> more expensive. All threads share the same address space.
Granted, but processes can't do preemptive multi-tasking on threads.
You *can* have a co-operative setup as in Windows16, but that's hardly
worth considering. The moment you rely on your kernel to do the
threading, you transit from user to kernel space. That's what causes
the overhead (which is higher in NT than in Linux, BTW).
There is no magic. You can't stop a running task without the intervention
of the kernel, or the cooperation of the task. In other words,
either the task (process/thread) gets preempted, or it yields (on I/O,
usually). A multi-threaded task (on a single processor) has only one
thread active at any time (evidently), and somehow the processor has to
balance the service it renders to the various tasks (with their threads).
In order to do this load-balancing, kernel code has to be executed, hence
user to kernel transitions take place.
Once in the kernel, there are the following possibilities:
1. The same taks is re-entered (because it's the only one on the run
list), and the kernel doesn't *need* (but might) to flush the
cache. Notice this is independent of the fact that threads might
be switched.
2. Another task is (re)started. Usually, the kernel needs to flush the
cache.
A well implemented OS will try to minimize cache-flushing, but this is
only an advantage if there's just *one* active task (hardly likely)
using threads to provide a multi-user service, as opposed to a number
of tasks providing the same service. Two tasks is all you need to
get rid of most of the advantage.
I'll skip the implications of multi-threading on separate processors.
The synchronisation problems caused by having a single address space
manipulated by two (or more) processors are left as an exercise for the
reader, the performance implications ditto ;-)
Process level threading is a fake, just as much as Windows16 multi-tasking
is a fake, simply because the active thread can monopolize the process'
time frame, and unless there is kernel support to assist thread switching
on preemption, there is no guarantee a thread will be well-behaved.

In any case, I stick to my guns and maintain that a well-designed OS
should have *both* kernel threads *and* fork facilities.

Dale Pontius

unread,
Jan 14, 1997, 3:00:00 AM1/14/97
to

In article <32dad7e9...@news.wr.com.au>,

free...@wr.com.au (Kent Tong) writes:
> Chris Marriott <ch...@chrism.demon.co.uk> wrote:
>
>>In article <5b8h15$q...@justus.ecc.lu>, "Stefaan A. Eeckels"
>><Stefaan...@ecc.lu> writes
>>>> threads are less efficient than doing a "fork"; that's the whole point
>>>> of multithreading - the fact that a thread context switch is much faster
>>>> than a process context switch!
>>>Why? the overhead is caused by switching from the application ring to
>>>the OS ring, and this happens both for a process and a thread switch.
>>>
>>
>>Because switching between threads within a single process simple
>>involves changing the registers and stack. A process context switch, on
>>the other hand, involves swapping the entire address space which is MUCH
>>more expensive. All threads share the same address space.
>
> What do you mean by swapping the entire address space? Doesn't
> it suffice to switch the current page table by setting a
> single page table register?
>
Well, sort of. You don't have to move all of that memory, but you
do have to mess with the hardware. It's still more overhead than a
thread switch.

Dale Pontius

unread,
Jan 14, 1997, 3:00:00 AM1/14/97
to

In article <5beidu$1...@justus.ecc.lu>,

Stefaan...@ecc.lu (Stefaan A. Eeckels) writes:
> In article <olgzlJAZ...@chrism.demon.co.uk>,
> Chris Marriott <ch...@chrism.demon.co.uk> writes:
>>
>> Because switching between threads within a single process simple
>> involves changing the registers and stack. A process context switch, on
>> the other hand, involves swapping the entire address space which is MUCH
>> more expensive. All threads share the same address space.
> Granted, but processes can't do preemptive multi-tasking on threads.
> You *can* have a co-operative setup as in Windows16, but that's hardly
> worth considering. The moment you rely on your kernel to do the
> threading, you transit from user to kernel space. That's what causes
> the overhead (which is higher in NT than in Linux, BTW).
> There is no magic. You can't stop a running task without the intervention
> of the kernel, or the cooperation of the task. In other words,

Agreed, but threads in OS/2 and NT are scheduled in the kernel. NT
also offers user-level threads, like Unix pthreads, called fibers.

Thread scheduling is more expensive when you have to go through the
kernel, but it's still less expensive than a process switch.

Patrick Haller

unread,
Jan 14, 1997, 3:00:00 AM1/14/97
to

Hi Andrew!

[..]
AG> In the absence of fork(), design of certain classes of server proces=
s
AG> is seriously constrained. In particular, servers where considerable =
work
AG> needs to be done as initialisation, but where it is *not* desirable =
to
AG> do work for different clients in the same process context, are quite=

AG> difficult to write cleanly, often resorting to shared memory in
AG> contexts where it is not strictly necessary.
Hmm, I still can't see an advantage of fork() over threads. For the above=

you could easily spawn new instances of the process via DosExecPgm or bre=
ak
the process into a small EXE and a (larger) DLL which does more managemen=
t
than. Furthermore just copying a running process could cause some tough
problems regarding handles (especialle non-kernel handles like message
queueing, etc.) and maybe the blocking IDs. =


AG> On the other hand, some other classes of servers are harder to
AG> implement efficiently if fork() is available, but not threads.
I'm really convinced this is the overwhelming majority :)

__
|_)
cu/2 |atrick
[Team OS/2]


Patrick Haller

unread,
Jan 14, 1997, 3:00:00 AM1/14/97
to

Hi Stefaan!

[..]
>> threads are less efficient than doing a "fork"; that's the whole poin=
t

>> of multithreading - the fact that a thread context switch is much
>> faster
>> than a process context switch!

SAE> Why? the overhead is caused by switching from the application ring =
to
SAE> the OS ring, and this happens both for a process and a thread switc=
h.
A thread creation does not require to copy the page table nor creating a
new process structure. Nor does it introduce problems with handles of any=

sort, which might otherwise take computing time to be resolved. Plus
threads do not need setting up shared memory, etc. and they often elimina=
te
the need for asynchronous calls. Imagine a thread providing the main
process with data gathered from serial ports, etc.

Perhaps someone could do exact benchmarking of fork() and beginthread()
alone.

Patrick Haller

unread,
Jan 14, 1997, 3:00:00 AM1/14/97
to

Hi Stefaan!

[..]
SAE> Granted, but processes can't do preemptive multi-tasking on threads=
=2E
Of course you can. Have fun watching OS/2 doing it :) Actually OS/2 does
only know threads as "executable units". A process is just a logical
structure containing thread0. =


[..]
SAE> I'll skip the implications of multi-threading on separate processor=
s.
SAE> The synchronisation problems caused by having a single address spa=
ce
SAE> manipulated by two (or more) processors are left as an exercise for=

SAE> the reader, the performance implications ditto ;-)
Hmm, this point is adressed by the semaphores and spinlocks available in
the OS/2 SMP Kernel. But I can't see fork() being faster or having anothe=
r
advantage here. Performance relys on the caching mechanism of the
participating processors.

[..]
SAE> The moment you rely on your kernel to do the threading, you transit=


from user to kernel space. That's what causes

SAE> the overhead (which is higher in NT than in Linux, BTW).
But overall, the context switch between threads is still significally
faster than between processes.

It seems to me you have not used threads so far in your programs. Many
advantages first show up when you have to do asynchronous operations, sma=
ll
I/O threads, etc. and simultaneously keep a responsive application
frontend. For such purposes, threads come VERY handy whereas fork()
introduces a fair amout of development overhead plus it can't really
replace threads.

John Currier

unread,
Jan 14, 1997, 3:00:00 AM1/14/97
to

hal...@zebra.fh-weingarten.de (Patrick Haller) wrote:

[snip]


>Perhaps someone could do exact benchmarking of fork() and beginthread()
>alone.

That would be an OS-specific benchmark. Since the OS in question (OS/2)
does not have fork(), then how do you propose we do benchmarking of it?

David Charlap

unread,
Jan 14, 1997, 3:00:00 AM1/14/97
to

Kent Tong <free...@wr.com.au> wrote:
>Chris Marriott <ch...@chrism.demon.co.uk> wrote:
>
>>In article <5b8h15$q...@justus.ecc.lu>, "Stefaan A. Eeckels"
>><Stefaan...@ecc.lu> writes
>>>> threads are less efficient than doing a "fork"; that's the whole point

>>>> of multithreading - the fact that a thread context switch is much faster
>>>> than a process context switch!
>>>Why? the overhead is caused by switching from the application ring to
>>>the OS ring, and this happens both for a process and a thread switch.

>>>
>>
>>Because switching between threads within a single process simple
>>involves changing the registers and stack. A process context switch, on
>>the other hand, involves swapping the entire address space which is MUCH
>>more expensive. All threads share the same address space.
>
>What do you mean by swapping the entire address space? Doesn't
>it suffice to switch the current page table by setting a
>single page table register?

Yes, but:

- Page tables and page table entries can be swapped out. Paging them
in from disk is really slow. This may happen if memory is severely
overcommitted and the process being switched to was idle for a
significant amount of time.

- whenever page tables are switched, the chip has to dump its at least
some of its page table cache and load new entries from RAM.
Hopefully that is in the chip's L1 or the motherboard's L2 cache,
but it might have to go all the way to main RAM. In any case, it's
not a fast procedure.

Switching thread-context within a thread doesn't involve any of this.

For details, I suggest you get a copy of "The Design Of The Os/2
Operating System" by Deitel and Kogan. It's very interesting reading.

+----------------------+------------------------------------------------------+
| David Charlap | The contents of this message are not the opinions of |
| da...@visix.com | Visix Software, nor of anyone besides myself. |
| Visix Software, Inc. +------------------------------------------------------+
| Member of Team-OS/2 | I do not give permission to use my name and address |
+----------------------+ in any commercial mailing list database. If my name |
| is in your database, please remove it immediately. |
+------------------------------------------------------+

Chris Marriott

unread,
Jan 14, 1997, 3:00:00 AM1/14/97
to

In article <32dad7e9...@news.wr.com.au>, Kent Tong
<free...@wr.com.au> writes

>What do you mean by swapping the entire address space? Doesn't
>it suffice to switch the current page table by setting a
>single page table register?

Yes, but this is something which doesn't have to be done in a thread
context switch. The point that I'm trying to make is that a process
context switch is HUGELY more "expensive" than a thread context switch;
don't take my word for this - test it for yourself!

David Charlap

unread,
Jan 15, 1997, 3:00:00 AM1/15/97
to

Chris Lawrence (Contra) <claw...@cup.hp.com> wrote:

>Jim Brooks (jbr...@swbell.net) wrote:
>: Why doesn't OS/2 have fork() built into the kernel?
>
>Because the OS/2 process model doesn't really have a concept of
>fork(). Its a significantly different process model from Unix.

>
>: Cloning a process is a slick way to build a program
>: which can break itself into threads. Local thread data
>: can be accessed very quickly when fork() is used,
>: just call malloc(), and the same pointer can be used
>: in all threads.
>
>Whoa. This is not true. The fork() call duplicates the entire data
>and text segments. It does *NOT* give both processes access to shared
>data segment.

You read his post too quickly. He said "Local thread data". Meaning
non-shared information.

BTW, if the process allocates shared memory, then the forked process
will still have access.

Basically, I think he's pointing out the fact that memory semantics
are reversed when you use fork instead of creating threads. When you
use fork, all data is private unless explicitly allocated as shared.
When you use threads, all data is public unless explicitly allocated
as thread local.

>Note however that there is a partial and very limited simulation of
>fork() under the OS/2 EMX libraries.

The biggest problem with this is that you can't use it when the -Zomf
and -Zsys flags are used - meaning you can't link to non-EMX code.
But that's OK, IMO, since I would only want to use fork for porting
UNIX apps, and they wouldn't require access to OS/2 libraries.

Chris Marriott

unread,
Jan 15, 1997, 3:00:00 AM1/15/97
to

In article <5beidu$1...@justus.ecc.lu>, "Stefaan A. Eeckels"
<Stefaan...@ecc.lu> writes

>Process level threading is a fake, just as much as Windows16 multi-tasking
>is a fake, simply because the active thread can monopolize the process'
>time frame, and unless there is kernel support to assist thread switching
>on preemption, there is no guarantee a thread will be well-behaved.

But on NT/Win95, the operating system schedules threads, not processes.
The fact that threads belong to processes is, to a certain extent,
irrelevent; pre-emption and scheduling is done on a per thread, not a
per process basis.


>
>In any case, I stick to my guns and maintain that a well-designed OS
>should have *both* kernel threads *and* fork facilities.

I'm afraid that I too must stick to my guns and maintain that "fork" is
irrelevent in a modern multithreaded operating system. I think we'll
just have to "agree to differ" about that :-). I believe that a well-
designed multithreaded application will, in all cases, be more efficient
than an equivalent "multi process" system.

Jon Hornstein

unread,
Jan 23, 1997, 3:00:00 AM1/23/97
to

Pardon the pun but I've been following this thread an want to put my 2
cents (no longer legal tender in Australia) in as I use both OS/2 and
Solaris which has both fork and solaris/posix threads.

When I started coding on Solaris with my long time OS/2 background I
thought great get rid of forks and lets introduce threads. I however
never came across the following reasons why sometimes forks are BETTER
than threads. I don't want to discuss why threads are better than
forks as it seems already to have been amply covered already in this
thread.

I see three obvious advantages with forks over threads in the Solaris
situation. I cannot obviously comment on the OS/2 situation.

On Solaris the way threads are implemented under the "hood" is
different that of OS/2.

I believe on OS/2 there is only thread scheduling. This is complicated
by the fact of thread priorities etc. Similarily under Solaris
processes and threads are scheduled as light weight processes (LWP).
Each LWP is treated identically by the processes scheduler.

Don't ask me the implications of this difference, I'd like to know the
answer to that myself!

Another difference is the way signals work.
On OS/2 if in the rare case you want to use signals, they are always
handled by thread 1 (the main thread).
On Solaris all threads receive notification that a signal has
occurred. Solaris programmers that I've seen have no end of problems
running multithreaded code and signals together and I feel these
mechanisms are basically incompatible. Signals traditionally were a
way async events could be passed to a single threaded processes as
traditionally existed on most UNIX machines. Now with threads many of
the reasons signals were being used may no longer exist. Further
system calls under UNIX get interrupted by signals causing them to
return errors indicating a signal has occurred.

The first thing that distinguishes threads from forks is that trashing
code on a thread in a multi threaded single process application will
have dire consequences on the application. Trashing code on a forked
process will "generally" only trash the process not the application.

As a programmer on a solaris system, if the system runs more slowly
because I'm forking applications instead of just a threaded
application I may suffer a few sleepness nights trying to think up
ways to make my application more efficient.
If one of my threads has an exception due to some state I never
anticipated and didn't pick it up during testing, for one transaction
and the current forked process crashes , someone will write a fault
report and I'll look into it when I get into work next day.
If that same thread crashes and the application doesn't get
implemented using forks and the whole application crashes I generally
wont go home until the problem is fixed (Mission Critical Applications
don't you just love 'um). My point being it's not just a matter of
fixing buggy code it's a matter of reliability of the whole
application.

The above example may be an exaggeration but it does highlight the
point that a firstly, forks reduce coupling between software
components in applications and hence provide for more reliable
applications.

The second point is because there is less coupling with forked
applications the runtime libraries don't have to maintain a barrage of
semaphore locks to maintain their resource integrity.
This is especially important in the case of CPU vrs I/O bound
applications. Threads are great for I/O bound applications but you get
very liitle speedup from multithreading lots of CPU bound code. The
semaphore coupling I believe greatly reduces the effective CPU
processor bandwidth. Here OS/2 and especially developers has always
had a problem, the time the main thread can be locked up for. As a
rule of thumb the main thread should not be locked up for more than
1/10 of a second. This is the OS/2 "golden" rule but we all know OS/2
PM interface can become very unresponsive. It is suggested that
activities that will break the golden rule should be threaded off. In
the case of CPU bound threads is there coupling between the main
thread and other threads that slow down the message handling of the
main thread? Would you ever put a critical section over CPU bound code
tor even make it of "time critical" class.


Following on from the second point my final point is do do with CPU
bound applications and the architecture of the machine. On the Solaris
2000 computer I use we have 4 sparc CPU's with over 1Gbyte of RAM
shared between them (MISD).
I assumed well if the system was idle which it was, 4 threads should
ran as fast as one thread on a 4 CPU system. My logic being that each
thread is distributed to a separate CPU's, each takes X time to
execute it should complete the 4 threads in X time.
What I in fact found was that the solaris 2000 it was taking 4X time
to execute my threads. NO speedup what a waste of CPU's. My software
was being coupled somehow and where! The only resources the threads
required was CPU instruction time and C/C++ runtime libraries code.
I'll leave to you to speculate why, would this have occurred on a MIMD
architecture machine!
I assume this phenemenon would have disappeared if I were running 4
processes. Each process would have taken X time to execute rather than
4 X time with the threads example.


Jon


Paul.E...@hrnowl.lonestar.org

unread,
Jan 23, 1997, 3:00:00 AM1/23/97
to

-----BEGIN PGP SIGNED MESSAGE-----

Because fork is usually stupid!

Usually when one uses fork one wants to start another process
to do something different. Often the resources of the old
processes are not used.

When unix was designed, process creation was planned to
be cheap. This is not the the case for OS/2 processes.

Fork can cause logic errors! Imagine that a C++ process
is forked. Every outstanding C++ object will be duplicated
without its constructor being called.
The destructor in the forked process will be called even
though the constructor was never called.
If the constructor does something outside the realm of
the program this will cause a logic error comparable
to constructing an object by byte wise copy for an
object not designed for this. Objects may have resources
that fork does not and cannot know about.


I believe that if UNIX were being designed today fork
would be left out.

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3
Charset: cp850

iQCVAgUBMubwvvBUQYbUhJh5AQGAgwP/VPMK8vvT8ENQL29IxKaj1sIUfOo9ddW9
pLgUA9zIiXP+v3WVRppEZyjyLV6+8xn4YMgZxG6Kv8BUVpDTsn7Op15HqMkv/uiX
1wQfme/5/F4WxOUrYa5hu8avDt1jmt5C7sKym5lQcBZQEwiz9eapS2P+9qDZmyBj
tMD83xeWKJ8=
=/qng
-----END PGP SIGNATURE-----


Frithiof Jensen

unread,
Jan 23, 1997, 3:00:00 AM1/23/97
to

In article <5c637m$4ol$1...@preeda.internex.net.au>, sul...@connexus.apana.org.au (Jon Hornstein) says:
>
Hi Jon,

After reading all the technical pros & cons of threads vs. forks it is refreshing to
see someone considering the *overall environment* where the program has to be used!


===============================================================================
The above article is the personal view of the poster and should not be
considered as an official comment from the JET Joint Undertaking
===============================================================================

Chris Lawrence (Contra)

unread,
Jan 23, 1997, 3:00:00 AM1/23/97
to

Jon Hornstein (sul...@connexus.apana.org.au) wrote:

: Following on from the second point my final point is do do with CPU


: bound applications and the architecture of the machine. On the Solaris
: 2000 computer I use we have 4 sparc CPU's with over 1Gbyte of RAM
: shared between them (MISD).
: I assumed well if the system was idle which it was, 4 threads should
: ran as fast as one thread on a 4 CPU system. My logic being that each
: thread is distributed to a separate CPU's, each takes X time to
: execute it should complete the 4 threads in X time.
: What I in fact found was that the solaris 2000 it was taking 4X time
: to execute my threads. NO speedup what a waste of CPU's. My software
: was being coupled somehow and where! The only resources the threads
: required was CPU instruction time and C/C++ runtime libraries code.
: I'll leave to you to speculate why, would this have occurred on a MIMD
: architecture machine!
: I assume this phenemenon would have disappeared if I were running 4
: processes. Each process would have taken X time to execute rather than
: 4 X time with the threads example.

AFAIR Solaris will not distribute threads across CPUs in an SMP
architecture. OS/2 will. As a result moving an MT application to an
otherwise idle SMP box may have little or no effect/improvement under
Solaris, but will get significant gain under OS/2.

Note: This would explain your observations above.

P.S. Why isn't 2 cents legal tender in Oz? Did they finally get rid
of the 1 cent coin? (Used to live in Brisbane Qld)

--
J C Lawrence Internet: co...@ibm.net
---------------(*) Internet: claw...@cup.hp.com
...Honorary Member Clan McFUD -- Teamer's Avenging Monolith...

alex korobka

unread,
Jan 26, 1997, 3:00:00 AM1/26/97
to

Jon Hornstein (sul...@connexus.apana.org.au) wrote:
...
: What I in fact found was that the solaris 2000 it was taking 4X time

: to execute my threads. NO speedup what a waste of CPU's. My software
: was being coupled somehow and where! The only resources the threads
: required was CPU instruction time and C/C++ runtime libraries code.
: I'll leave to you to speculate why, would this have occurred on a MIMD
: architecture machine!
: I assume this phenemenon would have disappeared if I were running 4
: processes. Each process would have taken X time to execute rather than
: 4 X time with the threads example.

Did you use pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) before
pthread_create(...)?

Alex


R. Pawlitzek

unread,
Feb 10, 1997, 3:00:00 AM2/10/97
to

In message <5ceq8l$6...@abel.ic.sunysb.edu> - al...@trantor.pharm.sunysb.edu (ale
x korobka) writes:
>Jon Hornstein (sul...@connexus.apana.org.au) wrote:
>....


For more information on pThreads programming check:

Pthreads Programming
A POSIX Standard for Better Multiprocessing
by Bradford Nichols, Dick Buttlar & Jacqueline Proulx Farrell
O'Reilly & Associates, Inc.
ISBN 1-56592-115-1

An excellent book about programming using threads!

Hope this helps
Rene Pawlitzek, ETH
http://129.173.21.68

0 new messages