Re: how to resume a sleeping thread
- From: Eric Sosman <Eric.Sosman@xxxxxxx>
- Date: Fri, 16 Nov 2007 12:21:21 -0500
ramsailu@xxxxxxxxx wrote On 11/16/07 10:45,:
Hi All,
We have a daemon that runs on Fedora Linux. We are using pthreads for
request service. For every request that it gets it will span a new
thread. Every new thread has to perform some work and writes the
message into socket to some external server. This message will have
the thread_id also. After writing the data it has to go to sleep mode,
till it gets the response.
There is a dedicated thread (aka receivethread) takes care of getting
all the responses back from external server. This receivethread
receives the response and gets the threadid from the response and it
should resume relevant thread that is sleeping. At any given time we
will have 100 or more clients talking to this Daemon.
1) How to keep the thread in sleep mode till we get the response?
Make it wait for something.
2) How to resume the sleeping thread from another thread (aka receive
thread)?
Make the something it waits for happen.
1) We thought of using conditional signals. But for every thread we
have to maintain wait and conditional signal pair. We thought it is
not feasible...
Why not?
2) And also thought of using sem_wait and sem_post pairs. After
sending the message thread will block on a sem_wait. Once after
getting the response receive thread will post sem_post. But for each
and every thread we have to maintain this pair. We thought which is
not feasible...
Why not?
Any suggestions will be appreciated. Thanks
Presumably each worker thread performs action A and
sends a result, then waits for a response, then performs
action B (and maybe it sends another result and waits for
another response and performs action C and so on, but
let's just look at A and B for now):
/* worker thread */
x1 = do_A();
send_result(x1);
x2 = await_response();
do_B(x1, x2);
The usual way of approaching this is to begin by
inventing a "session" object, a struct or something that
holds "everything you need to know about this stream of
requests and responses." Once you have done this, it
becomes possible to execute A and B in different functions,
and even (this is the crucial point) in different threads.
Given a pointer to a session object and the knowledge
that "it's time to do A" or "it's time to do B," any
thread at all can do the necessary work.
Why is this worth doing? Because you no longer need
to create hundreds of threads just to keep track of what's
next for all those hundreds of sessions. Look at the code
above: Most of the time is spent in await_response(), and
the only thing the thread is doing for you is to maintain
its own local variables and the knowledge that "B is next."
That's what most people call a waste of a perfectly good
thread that could be doing something else in service to
some other session instead of just sitting around tying
up memory.
So, once you've pulled the session information out of
the thread's local variables and put it in an explicit
struct, what next? The obvious thing is to have the
receiver thread put each incoming message on a queue and
awaken a worker to handle it. Note that it no longer
matters which worker gets the message: Everything the
worker needs to know is in the session struct, so any
thread can service any session. The worker goes off and
does whatever it is supposed to, and then goes back to
the queue to pick up the next "work order," which could
be for the same session or for an entirely different one.
Of course, the clients no longer try to specify which
thread will handle their messages; they instead identify
which session they belong to and let themselves be served
by the "next available cashier."
An immediate benefit is that you no longer need to let
the clients dictate how many worker threads you run; you
can choose their population to suit the resources of the
machine you're using at the moment. If the machine can
comfortably run eight workers, that's how many you run:
if hundreds of clients "speak" at about the same time,
some of them will wait in the queue, but the workers will
churn through all the messages as fast as the machine can
manage. You will almost always get better results from a
small number of busy threads than from a large number of
usually-idle threads.
This "thread pool" scheme is not the solution to all
such problems, but IMHO it should be the default approach,
the one you take until and unless you find reason to think
it isn't appropriate.
--
Eric.Sosman@xxxxxxx
.
- References:
- how to resume a sleeping thread
- From: ramsailu@xxxxxxxxx
- how to resume a sleeping thread
- Prev by Date: how to resume a sleeping thread
- Next by Date: Re: Interesting GCC optimization, but is it legal if POSIX thread support is claimed?
- Previous by thread: how to resume a sleeping thread
- Index(es):
Relevant Pages
|