Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Mar 2003 18:43:11 +1100
From:      Peter Jeremy <peterjeremy@optushome.com.au>
To:        Jeff Roberson <jroberson@chesapeake.net>
Cc:        Julian Elischer <julian@elischer.org>
Subject:   Re: 1:1 Threading implementation.
Message-ID:  <20030327074311.GB18940@cirb503493.alcatel.com.au>
In-Reply-To: <Pine.BSF.4.21.0303261154100.52134-100000@InterJet.elischer.org>
References:  <20030326031245.O64602-100000@mail.chesapeake.net> <Pine.BSF.4.21.0303261154100.52134-100000@InterJet.elischer.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Mar 26, 2003 at 12:30:52PM -0800, Julian Elischer wrote:
>On Wed, 26 Mar 2003, Jeff Roberson wrote:
>> First, if your application has more threads than cpus it is written
>> incorrectly.
>
>Not neccesarily. that's just one way of looking at threads. Active
>component threaded programs use threads as a programming model
>(see above) and it is a perfectly valid way of writing a program.

I'd go so far as to say that the only case where relating real CPUs
and threads matters is for compute-bound processes where the only
purpose of threading is to get >100% CPU.

If you consider an arbitrary server/daemon process, there are a
limited number of basic mechanisms you can use to handle more than
one client:
1) One (single-threaded) process per client (eg telnetd, sshd)
2) One process with one thread per client (possibly per direction)
3) One process explicitly using select()[*] to support multiple clients.

Each approach has its own advantages and disadvantages and each
approach requires different support code to handle new clients and
switching between clients.

Obviously, you can combine the approaches but this means you have the
support infrastructure for both basic mechanisms as well as additional
code to decide which mechanism to use.  Apache is a combination of 1
and 3 - but needs a process dedicated to distributing incoming requests.

In general, if you're going to go the effort of threading your server,
why go to the additional effort of adding a select() handler in each
thread?  The big advantage of 1 and 2 is that the core is very simple:
	while (!eof(input)) {
		read input
		do some processing
		write output
	}
whereas the core of 3 requires building and testing FD sets and
making sure that you only block in the select().  This generally
makes the code far less clear.  You can also potentially reduce
the overall throughput because there are multiple scheduling layers.

[*] For "select()", read "select() or poll() or kqueue()"

Peter



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030327074311.GB18940>