Re: linux-kernel-digest V1 #4149

Larry McVoy (lm@bitmover.com)
Thu, 15 Jul 1999 16:33:57 -0600


: I could just as easily give you a situation that lends itself to
: threads. What about when I have a process with several threads handling
: I/O events, and I get a SIGIO. I do NOT want any one particular thread to
: receive the signal (that thread may be busy with a really long queue of
: I/Os to process already). I do NOT want all threads to receive the signal
: (one is fine, thanks). I want the signal to go to a thread (any thread)
: that can handle it. THAT is what POSIX thread semantics do for signal
: handling.

This is completely orthogonal to the threads/process discussion. The same
problem exists (and has been solved multiple ways) for processes. I have
N processes (in Apache, for example), 1 or more of which may be blocked
in select waiting for the I/O. The original BSD implementation of select()
woke up all of them. Many operating systems have implemented "wake up 1"
semantics, where only one of the N blocked processes are awoken. There are
other ways to solve the problem as well.

The point is that this isn't a thread issue - it's a generic issue. If you
solve it for processes, you've also solved it for Linux threads (aka clones).
If you don't solve it for processes, I suppose you can conjure up a world
view in which you decide to only solve it for threads, but that's a hack,
and it's the sort of hack which is extremely unlikely to be acceptable by
Linus (or any other reasonable architect). The right answer is to solve it
for the general case; then it works for threads and it works for problems
that don't need the thread model (HTTP servers, for example).

: Different models for different needs, but processes and process groups
: can't do everything. Not everyone who wrote POSIX is stupid.

Linus said at BALUG not too long ago that there are two kinds of standards,
the good kind and the bad kind. The good kind is when you've reached a
point that you are happy with a part of the system and are willing to
commit to not breaking those interfaces and semantics. Writing down the
interfaces in a formal way and assuring people that they will continue
to work is standard. P1003.1 is an almost perfect example of this.
These sorts of standards are Good Things (tm) and are to be encouraged.

The other kind of standard is created when a set of interfaces don't
exist, but there is a need for them to exist. Rather than wait for
industry to figure out the right answer, a committee of people ``decide''
on the right answer. These standards are almost universally bad things.
You can't, you simply can't, figure it all out in advance. You need to
wait and see how things are used, how they are implemented, what works,
what doesn't. A really brilliant mind, with a lot of experience, left
alone to do the whole thing can sometimes (it's rare but it does happen)
write down the right answer. But a committee of people just doesn't get
it right. The later 1003.x standards are examples of this. There are
all sorts of hacks in there that just aren't right. If the POSIX guys
could do the thread stuff all over again, after understanding the Linux
(aka Plan 9) clone() interface, I'd lay 10:1 odds that the POSIX threads
interface would be very, very different.

: > This is just silly beyond words. The Linux model is _clearly_ the
: > superset of the LWP model. Under Linux I can kill a specific thread
: > or all of the threads, using the same interfaces Unix has had since v6
: > or earlier. Under the LWP model, I can kill all the LWPs.
:
: Actually, you can kill any one that is not blocking the signal at the
: point that you send it (or one that has it masked but is blocked in
: sigwait waiting to handle the signal). How do I do that under Linux right
: now?

No, you can _all_ that are not blocking the signal. How do I use kill(2) or
kill(1) to kill a specific one of them?

: I'm working on a patch that lets me do that... but it does add to
: the interface quite a bit, because now I need to distinguish between
: killing a whole process (group of tasks cloned with CLONE_PID) or killing
: a task.

I think CLONE_PID is a crock of doo doo and should be shot dead. It's the
wrong answer. They aren't one process, they are N processes. Pretending
that they are one process is just the wrong answer.

: Not from outside the process, anyway. A process is a single entity to
: outsiders... under normal operation (not debugging), one process playing
: with the internal details of how another process is implemented seems
: pretty dumb to me.

Using that logic, we should just remove the kill(2) interface. I doubt
that, upon reflection, you really want to do that.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/