No. They are better -- while mostly keeping the same API. As stated
above, most multithreaded OSs define a thread separately from processes.
Linus Torvalds has defined that a thread is a "context of execution"
(COE). This means that only one process/thread table and one scheduler
is needed. Also the scheduler has been optomized so that the switching
time for threads vs. tasks varies little--about 1.7us (threads) and 1.8us
(fork) on a 75MHz Pentium.
Traditionally, a thread was just a CPU (and some other minimal state)
state with the process containing the remains (data, stack, I/O, signals).
This would lend itself to very fast switching but would cause basic problems
(e.g. what do "fork()" or "execve()" calls mean when
executed by a thread?).
Consider Linux threads as a superset of this functionality: they still
can switch fast and share process parts, but they can also identify what
parts get shared and have no problems with execve() calls. There are four
flags
that determine the level of sharing:
Clone Flag Values
| #define |
CLONE_VM |
0x00000100 |
| #define |
CLONE_FS |
0x00000200 |
| #define |
CLONE_FILES |
0x00000400 |
| #define |
CLONE_SIGHAND |
0x00000800 |
| #define |
CLONE_PID |
/* not
fully implemented */ |
There has been a lot of talk about "clone()". The system call
(please note: "low level") clone() is an extension
to fork(). In fact, clone(0) == fork(). But with the above #define's, any
combination of the VM, filesystem, I/O, signal handlers and process ID
may be shared.