Re: What's the connection between objects and threads?
On 18 mai, 11:43, darren <minof...@gmail.com> wrote:
On May 18, 1:13 am, ManicQin <Manic...@gmail.com> wrote:
[...]
If you could shed some light on your project maybe people
could give a more precise counsel on the MT method you
should use...
Its a multithreaded web server using pthreads and the socket
api (hey everybody else in my class looking for ideas :) ).
Here's my basic algorithm:
1. main() makes a singleton ServerKernal object to control program
flow
2. ServerKernal listens for requests on a specified port. this is done
by creating a thread that loops and continuously accepts connections.
There's really not necessarily a reason to start a separate
thread for this.
3. A successful accepted connection is put into a queue (from the STL
library).
4. Meanwhile, back at the ranch, another thread is created and running
that continuously checks for entries into the queue.
5. if an entry is in there, a new thread is spawned to handle the
request. That thread then dies.
That sounds like extra complication as well. What's wrong with
just starting the connection thread immediately when you get the
connection?
What do you think of this algorithm?
What are the constraints concerning shutdown? If you don't have
any (i.e. the only way to stop the process is to kill it), then
your connection threads are basically fire and forget: you don't
really need to keep any trace of them (which means that you
don't have any "thread" objects). In fact, unless the server
needs to access shared in memory data, it may be preferable to
use processes instead of threads. (That's what a lot of
traditional servers do: FTP, telnet, etc.)
A couple of things i'm thinking about:
1. As per the reason i created this post, I was thinking about how
objects related to threads.
They don't, necessarily. Fundamentally, the "thread" object is
somewhere in the OS, not in your code. If the thread should do
something resulting in returned data, and you will eventually
have to wait for it (join), then some sort of object is probably
desirable in your application. This object is traditionally
called a "thread" as well, but it's important to realize that it
isn't really the thread itself, it's just an interface to
certain characteristics of the thread the OS is maintaining. If
you need to support clean shutdown, then you'll need some means
of keeping track of which threads are active (which might result
in "thread" objects as well), so that you can notify them of a
desired shutdown, and wait until all of them have shutdown. But
in the simplest case of a server, it's fire and forget for each
connection. Just start the thread, and forget about it; the
thread takes care of everything itself. (Conceptually, you
might think of it as an object, and within the OS, it certainly
is, but practically, in your code, at least with pthreads or
WinThreads, it's a function with its own stack, and that's it.)
At first I was thinking that an object should create a thread.
this has been advised as bad (thanks for the advice!).
In the end, it is the call to pthread_create which will create
the thread. Depending on what you want to do with it, you might
want to create an object which manages this information. The
type of this object should not be a base class, nor should
instances be members of another object. Practically, doing so
leads to race conditions; conceptually, you're modeling
something in the OS backwards from the way the OS implements it:
in the OS, it is the thread which owns the functions it is
executing, and not vice versa---in other words, the "object"
which you execute is a member or base class of the thread, and
not vice versa. In C++, supposing you need a thread object, you
can do this in three ways: the type of the thread object can be a
template on the object to be executed, it can take over
ownership of an object create elsewhere, or it can make a copy
of an object you pass its constructor. The latter is what
Boost does, but it requires some pretty tricky template
programming (not in Boost threads, but in Boost functions, which
Boost threads uses) to work. The second solution is probably
the easiest for a beginner to implement; you define an abstract
base class Threadable or Runnable, with an pure virtual
function run, and you pass a pointer to this to your thread
object.
Now I'm thinking that instead, threads should create objects,
and destroy them before the thread ends.
Almost certainly. And each thread has its own stack on which it
can do this.
for example, when a request is in the queue, a thread is
created to handle it. Within this new thread, a
RequestHandler object is instantiated. It's methods are used
to process the request. The object is then destroyed.
Finally, the thread ends.
2 I was thinking about thread pools. Maybe there could be 10
threads set up, waiting for requests. I dont know much about
thread pools yet though. It may not be appropriate. Or, maybe
the threads could be sleeping, then awoken by signaling when a
request enters the queue.
The usual way to use thread pools is for all of the threads to
wait on a message queue. The listener thread then sends the
incoming request to the queue; depending on design constraints,
it may decide to create an additional new thread first, if no
thread is currently waiting, or to reject the connection, if no
thread picks up the message after a specified time.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34