Re: Informing UI thread of target for sending messages?
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Sat, 12 Jan 2008 01:21:22 -0500
See below...
On Fri, 11 Jan 2008 19:57:06 -0700, "L.Allan" <lynn.d.allan@xxxxxxxxxxxxxxxxxxxxx> wrote:
********Joe: > Not sure why you fastened on this notion that a thread needs to
receive a message. If you
were doing a thread pool, sure, but then the thread would not terminate,
it would only
finish its computation and wait again. But a worker thread using an I/O
Completion Port
(which is a better model for thread pooling) can do this, and it doesn't
have to be a
worker thread
****
vvvvvvvvvvvvvvvvvvvvvvvvvv
Lynn: I guess I've lost track of what you are recommending. Previously I
thought you were strongly suggesting using ui threads with
PostThreadMessage. But now it seems worker threads would be better.
It depends on what you are trying to do. If you want a thread pool with a thread that is
waiting for data, a UI thread is a better choice. But then you described your problem in
a way that makes it obvious that you don't need a UI thread because you're not going to be
waiting for any messages!
****
****
I possibly have incorrect assumptions ... that creating 4 worker threads for
each search would be excessively "expensive". I had in mind that these 4
threads (ui or plain worker) are created once, and are blocked waiting
"work" to do. With ui threads, this unblocking would be with a message. With
non-ui worker threads, this unblocking would be something like an event.
That's a thread pool. And UI threads are still not a good choice; an I/O Completion Port
and PostQueuedCompletionStatus works better, because PostThreadMessage requires that you
know what thread to send it to; PostQueuedCompletionStatus just activates whatever thread
is waiting.
****
*****
But if worker threads are cheap/fast to create over and over, then that
would greatly simplify things. I guess there isn't all that much more than a
pointer to the function, some stack space, and enough "glue" to swap
registers.
It's also an issue of a sense of proportion. Yes, creating threads has a cost, but then
you are going off and running some MASSIVE search (relatively speaking) and therefore the
cost of thread creation would be unnoticeable. If you plan to reuse the threads and need
efficiency, you will get massive improvements in efficiency by dropping the idea of
reading the file more than once. That's where your real costs are going to be
*****
****
So ..... the search is kicked off by the end-user; 4 threads are created and
they tackle their quarter of the memory buffer to do their part of the
search. They get done, report back, and kaput. The main gui thread organizes
and presents the results.
You have to balance costs. If you want a pool of threads and want to process lots of
files, then you would simply queue up the files in the queue to be processed. The threads
will remove elements from the queue and process them. Each entry will designate the
target (which will not necessarily be a single variable, depending on what you are
searching for; if you are searching all 20 files for the same word that's different than
if you are multisearching for multiple words (it isn't that hard to generalize; one of the
things you pass into the thread via the parameter packet is a pointer to the "search
object" to update, and the threads post this pointer back when they are done).
****
****
Something to mention ... the time frame involved is perhaps 1/10 second on a
reasonable modern computer with a dual-core or core-2-duo. Anything over 2
seconds is sluggish. The code is already fast enough for a single file, but
I want it to be "knock your socks off" responsive with parallel search of
20+ files.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
****Joe: > You are hung up on the concept of UI threads. Drop it.
****
Using messaging, the synchronization is not required. Also, NEVER use
CCrticalSection;
the MFC synchronization primitves are crap and should be avoided. Note
that none of this
synchronization is required
****
vvvvvvvvvvvvvvvvvvvvvvvvvv
Lynn: Ooops ... now I recall reading that in an essay of yours ... my poor
brain is getting overloaded :-(
^^^^^^^^^^^^^^^^^^^^^^^^^
threadsleft = ::InterlockedDecrement(&m_curThreadCountStillWorking);
::InterlockedExchangeAdd(&m_foundCountOverall, foundcount);
m_foundCountPerThread[threadindex] = foundCount;
The first two use hardware-interlock instructions to achieve the
interlock, thus
eliminating the need for any other locking. The last one doesn't need
synchronization
because only one thread can have that thread index, so there is no
concurrent access
involved.
vvvvvvvvvvvvvvvvvvvvvvvvvv
Thanks ... I was wondering about whether the
m_foundCountPerThread[threadIndex] needed to be protected.
^^^^^^^^^^^^^^^^^^^^^^^^^
****
I've said this before: you're taking a simple problem and making it
difficult. Forget UI
threads. They add complexity without adding value.
****
Think about how to simplify threading. If you add synchronization, you add complexity.
See my essay about "the best synchronization is no synchronization"
joe
****
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- References:
- Informing UI thread of target for sending messages?
- From: L.Allan
- Re: Informing UI thread of target for sending messages?
- From: David Ching
- Re: Informing UI thread of target for sending messages?
- From: L.Allan
- Re: Informing UI thread of target for sending messages?
- From: Joseph M . Newcomer
- Re: Informing UI thread of target for sending messages?
- From: L.Allan
- Informing UI thread of target for sending messages?
- Prev by Date: Re: Get the handle of controls not reachable with the mouse
- Next by Date: Re: CDialog::OnCopyData, what does it do?
- Previous by thread: Re: Informing UI thread of target for sending messages?
- Next by thread: CCmdTarget::GetRoutingFrame call .. approach for UI threads to communicate results?
- Index(es):
Relevant Pages
|