User Interface Threads
Laurent POULAIN -- poulainl@club-internet.fr
Saturday, April 27, 1996
I am using VC++ 4.0 with NT 3.51 and I have a few
problems implementing User Interface Threads: each new thread
really slows down the system and somerimes, the program crashes.
I looked at VC++ samples (MTGDI) and in on-line doc, but
I can't find out where the problem is.
How can I implement User Interface Threads from a new
Appwizard application ?
Thanks,
Laurent POULAIN
E-Mail: poulainl@club-internet.fr
Niels Ull Jacobsen -- nuj@kruger.dk
Wednesday, May 01, 1996
At 18:12 27-04-96 +0000, you wrote:
>I am using VC++ 4.0 with NT 3.51 and I have a few
>problems implementing User Interface Threads: each new thread
>really slows down the system and somerimes, the program crashes.
>
> I looked at VC++ samples (MTGDI) and in on-line doc, but
>I can't find out where the problem is.
Unfortunately your problem description is a bit vague, so it's=20
hard to tell what the problem is.
A common design error when using multiple UI threads is to use=20
too many SendMessages (or functions which calls SendMessage)
to send messages to other threads. Every time you SendMessage to
a window belonging to another thread, you're forcing two context=20
switches.
This can really slow things down. It can also lead to deadlocks
if the other thread sends a message back.
=20
Perhaps if you could be a bit more specific as to what you're trying to do?
>
> How can I implement User Interface Threads from a new
>Appwizard application ?
>
> Thanks,
>
>Laurent POULAIN
>E-Mail: poulainl@club-internet.fr
>
>
>
Niels Ull Jacobsen, Kr=FCger A/S (nuj@kruger.dk)
Everything stated herein is THE OFFICIAL POLICY of the entire Kruger group
and should be taken as legally binding in every respect. Pigs will grow
wings and fly.
Laurent POULAIN -- poulainl@club-internet.fr
Friday, May 03, 1996
Niels Ull Jacobsen wrote:
>=20
> At 18:12 27-04-96 +0000, you wrote:
> >I am using VC++ 4.0 with NT 3.51 and I have a few
> >problems implementing User Interface Threads: each new thread
> >really slows down the system and somerimes, the program crashes.
> >
> > I looked at VC++ samples (MTGDI) and in on-line doc, but
> >I can't find out where the problem is.
>=20
> Unfortunately your problem description is a bit vague, so it's
> hard to tell what the problem is.
>=20
> A common design error when using multiple UI threads is to use
> too many SendMessages (or functions which calls SendMessage)
> to send messages to other threads. Every time you SendMessage to
> a window belonging to another thread, you're forcing two context
> switches.
>=20
> This can really slow things down. It can also lead to deadlocks
> if the other thread sends a message back.
>=20
> Perhaps if you could be a bit more specific as to what you're trying to=
do?
>=20
> >
> > How can I implement User Interface Threads from a new
> >Appwizard application ?
> >
> > Thanks,
> >
> >Laurent POULAIN
> >E-Mail: poulainl@club-internet.fr
> >
> >
> >
> Niels Ull Jacobsen, Kr=FCger A/S (nuj@kruger.dk)
> Everything stated herein is THE OFFICIAL POLICY of the entire Kruger gr=
oup
> and should be taken as legally binding in every respect. Pigs will grow
> wings and fly.
Actually, I'm trying to have several MDI windows, each
one running in its own thread. That's why I decided to use
User Interface threads.
Laurent "Fractalman" POULAIN
poulainl@club-internet.fr
Mike Blaszczak -- mikeblas@interserv.com
Wednesday, May 08, 1996
On Fri, 03 May 1996, Laurent POULAIN wrote:
> Actually, I'm trying to have several MDI windows, each
>one running in its own thread. That's why I decided to use
>User Interface threads.
Why would you want to do that? You'll really win nothing because the
separate threads will spend time blocking on eachother when they try to send
window management messages to eachother. It seems like lots of effort for
little gain.
.B ekiM
--
TCHAR szDisc[] = _T("These words are my own; I do not speak for Microsoft.");
John Addis -- jaddis@erols.com
Thursday, May 09, 1996
mikeblas@interserv.com wrote:
>
> On Fri, 03 May 1996, Laurent POULAIN wrote:
>
> > Actually, I'm trying to have several MDI windows, each
> >one running in its own thread. That's why I decided to use
> >User Interface threads.
>
> Why would you want to do that? You'll really win nothing because the
> separate threads will spend time blocking on eachother when they try to send
> window management messages to eachother. It seems like lots of effort for
> little gain.
>
I understand why you don't like this arrangement, but I can think of a number
of applications where it might make sense. The blocking time might not be nearly
as important as other decisions that lead one to choose this approach in the first
place.
More importantly, doesn't Jeffery Richter mention this approach in "Advanced Windows?"
I don't have my copy handy but I'm fairly certain of it.
--
John Addis Master of Time and Space
jaddis@erols.com C++, MFC, Win32, Win95, TCP/IP
"Invalid or missing REALITY.COM Universe halted."
Mike Blaszczak -- mikeblas@msn.com
Sunday, May 12, 1996
----------
From: owner-mfc-l@netcom.com on behalf of John Addis
Sent: Thursday, May 09, 1996 20:44
>mikeblas@interserv.com wrote:
>>
>> On Fri, 03 May 1996, Laurent POULAIN wrote:
>>
>> > Actually, I'm trying to have several MDI windows, each
>> >one running in its own thread. That's why I decided to use
>> >User Interface threads.
>>
>> Why would you want to do that? You'll really win nothing because the
>> separate threads will spend time blocking on eachother when they try to
send
>> window management messages to eachother. It seems like lots of effort for
>> little gain.
>>
> I understand why you don't like this arrangement, but I can think of a
number
> of applications where it might make sense. The blocking time might not be
nearly
> as important as other decisions that lead one to choose this approach in the
first
> place.
Would you care to share them? It's hard for me to understand why you'd want
to go through the trouble of designing and using with multiple threads in this
situation only to funnel things through a roadblock that deeply negates the
benefit of the design.
> More importantly, doesn't Jeffery Richter mention this approach in
> "Advanced Windows?" I don't have my copy handy but I'm fairly certain of
it.
Jeffrey Richter is a good author, but his mention of something doesn't make it
inherently right. You'd need to ask him for a justification of what he wrote:
I don't see any use for this kind of arrangement and can't be reasonably
expected to justify it.
> John Addis Master of Time and Space
Could you make me early for work, just once?
.B ekiM
TCHAR sz[] = _T("These words are my own; I don't speak for Microsoft.");
John Addis -- jaddis@erols.com
Tuesday, May 14, 1996
[Mini-digest: 2 responses]
Mike Blaszczak wrote:
>
> Would you care to share them? It's hard for me to understand why you'd want
> to go through the trouble of designing and using with multiple threads in this
> situation only to funnel things through a roadblock that deeply negates the
> benefit of the design.
First, I must disclaim: I did not in any way participate in the design
of the system I am about to talk about. I was brought in to the team
when the company was about to release the product to their unwitting
customers. Also, the system was written in Win16 so it was only single
threaded -- I feel that it could have benefited greatly from a
multi-threaded approach.
The primary purpose of the system was to allow users to search for,
view, and print documents from a collection of +/- 2000 CD Roms. The
data base was moderatley large: 248 Mb but not well designed. (I don't
blame this on the engineers/DBAs -- this one goes squarely on product
management. But that is another story...)
Users had to be able to view (up to 4 docs at a time, including auto
browsing of each) and print simultaneously. Spooling docs to print
manager was out of the question as it was not uncommon for the users to
want to queue up 50-100 documents of 50+ pages each of 300dpi images.
The system also had to be capable of driving a specific printer at rated
speed (45ppm, using a Kofax 9250 image-processing board)
Another, extremely important, thing to note is that the company building
this system was excessively greedy. They had been alone in their market
for a number of years. They liked to charge their customers as much as
humanly possible. Every single "page operation" had to be extensively
documented and logged for later billing purposes. In addition, the
company's clients were typically Wall Street investment firms or very
large law firms. They also required extensive accounting of page by
page operations but all used different accounting methods and prices.
Let me also say that the boxes that this system ran on had a minimum of
4 CD-Rom drives each. Some had as many as 10 drives.
This should give a fair picture of the system.
I'm not going to try to explain every place in the system that multiple
threads could be used to good advantage. I got tired of that months ago
and changed jobs. However...
In order to get the simultaneous multiple views and printing stuff to work they
(and this is hard for me to talk about) had a "daemon" process running in the
background. On every tick it would walk through its list of clients and call
a virtual function in each one. Yes, right across process boundaries. I still
have nightmares thinking about it.
They also carelessly littered "PeekMessage" loops all over the damn place. When
they got bitten by reentrancy they went back and created a "semaphore" system.
(What they actually did was roll their own very crude implementation of named
mutexes.) This actually introduced more yielding though it reduced reentrancy.
***Any amount of threads blocking on each other would have been prefereable to
the wild, unpredictable behaviour of this demonic process.***
I personally think that a separate thread for each document view would be workable
in this case because the amount of user interaction (and therefore events that
would spawn MDI window management messages) is small compared to the actual
amount of processing that was going on.
> > More importantly, doesn't Jeffery Richter mention this approach in
> > "Advanced Windows?" I don't have my copy handy but I'm fairly certain of
> it.
>
> Jeffrey Richter is a good author, but his mention of something doesn't make it
> inherently right. You'd need to ask him for a justification of what he wrote:
> I don't see any use for this kind of arrangement and can't be reasonably
> expected to justify it.
I'm not asking you to justify it. I have to agree with you and say that most of the
time it absolutely would not be worth it. But the question has popped up on the
list a number of times and when it does you dismiss it out of hand.
Given the frequency with which this question is asked perhaps some extra documentation
would be in order -- either in the product docs (which I know you have no control over),
an MSJ article, or the next edition of somebody's book?
> > John Addis Master of Time and Space
>
> Could you make me early for work, just once?
You'll need to see someone in miracles. Down the hallway, third door on your left.
> .B ekiM
btw: I enjoyed your article in May's MSJ. Do you have your hockey server running
full time yet? Go Penguins!
--
John Addis Master of Time and Space
jaddis@erols.com C++, MFC, Win32, Win95, TCP/IP
"Invalid or missing REALITY.COM Universe halted."
-----From: "Roderick Prince"
> More importantly, doesn't Jeffery Richter mention this approach in
> "Advanced Windows?" I don't have my copy handy but I'm fairly certain of
it.
Yes he does. He happens to mention it in Chapter One - When not to create a
thread. He does clarify it with - each application deserves its own thread and
also advocates MDI Child windows having their own thread (the point of your
question). He does not mention anything about how this technique affects the
process of communicating between MDI windows.
As for...
>> Why would you want to do that? You'll really win nothing because the
>> separate threads will spend time blocking on eachother when they try to
>> send window management messages to eachother.
... my knee jerk reaction was that structuring your application to make views
independent of one another would limit the overhead of context switches.
Scratch a little below the surface though and I think the act of Views
updating a documents data could cause a flurry of context switches as the
document tries to update all associated views. Therefore I think Mike is right
in his comments about blocking possibly negating the benfits of multiple
threads. The exception to this seems to me to be when you are implementing an
SDI application using the MDI framework as a container for loosely associated
views of data (ex. A view of your client list and another view of client
invoices both having different documents).
Happy trails,
Roderick...
----------
From: owner-mfc-l@netcom.com on behalf of Mike Blaszczak
Sent: Sunday, May 12, 1996 3:15 PM
To: mfc-l@netcom.com
Subject: RE: User Interface Threads
----------
From: owner-mfc-l@netcom.com on behalf of John Addis
Sent: Thursday, May 09, 1996 20:44
>mikeblas@interserv.com wrote:
>>
>> On Fri, 03 May 1996, Laurent POULAIN wrote:
>>
>> > Actually, I'm trying to have several MDI windows, each
>> >one running in its own thread. That's why I decided to use
>> >User Interface threads.
>>
>> Why would you want to do that? You'll really win nothing because the
>> separate threads will spend time blocking on eachother when they try to
send
>> window management messages to eachother. It seems like lots of effort for
>> little gain.
>>
> I understand why you don't like this arrangement, but I can think of a
number
> of applications where it might make sense. The blocking time might not be
nearly
> as important as other decisions that lead one to choose this approach in the
first
> place.
Would you care to share them? It's hard for me to understand why you'd want
to go through the trouble of designing and using with multiple threads in this
situation only to funnel things through a roadblock that deeply negates the
benefit of the design.
> More importantly, doesn't Jeffery Richter mention this approach in
> "Advanced Windows?" I don't have my copy handy but I'm fairly certain of
it.
Jeffrey Richter is a good author, but his mention of something doesn't make it
inherently right. You'd need to ask him for a justification of what he wrote:
I don't see any use for this kind of arrangement and can't be reasonably
expected to justify it.
> John Addis Master of Time and Space
Could you make me early for work, just once?
.B ekiM
TCHAR sz[] = _T("These words are my own; I don't speak for Microsoft.");
Mike Blaszczak -- mikeblas@msn.com
Friday, May 17, 1996
----------
From: owner-mfc-l@netcom.com on behalf of John Addis
Sent: Tuesday, May 14, 1996 08:09
> This should give a fair picture of the system.
I'm afraid I had a really hard time following you. I don't understand what
part of this system ran on clients, and which ran on servers... if any at all.
I'm assuming there was _some_ distributed processing going on, since you say
that some machines had 4 CD drives and some had 10, but you had 2000-some
CDs. That means that you had well more than 200-some machines, and they must
have done some sort of cooperative processing. I couldn't infer who was
creating threads on who's behalf and when.
> Yes, right across process boundaries.
> They also carelessly littered "PeekMessage" loops all over the damn place.
I'm not sure where they're multitasking, or what at all they won (besides job
security) for using multiple threads in this system. You've not presented me
with a situation where one thread would free up and get work done while
another would be blocking; you've implied that was happening with printing,
but printing shouldn't involve an MDI child window.
So, maybe I'm missing what benefit you really got out of having a
thread-per-view here.
> ***Any amount of threads blocking on each other would have been prefereable
to
> the wild, unpredictable behaviour of this demonic process.***
> got bitten by reentrancy ... rolled their own mutexes.
One [system based upon] unjustified hack(s) does not really net a win over any
other [system based upon] unjustified hack(s). That is, I think it's invalid
to compare a crazy collection of broken code with another crazy collection of
broken code. Since they've got so many broken building blocks (for instance,
treating the symptom of reentrancy crashing rather than taking the time to
write truly reentrant code) they don't really notice the other problems
inherent to their fundamental design.
Motorcycles (usually) have very interesting engines. The two bikes I've owned
have both had four cylinders. They also had four carburetors. Part of tuning
up these bikes was to make sure the carbs were synched. That is, you'd need
to make sure each cylinder was getting the same fuel/air mixture as the next
cylinder so that one cylinder would not have to do all the work others
weren't. It's very, very noticable when this happens: the bike really lugs
when you try to pop wheelies.
It sounds like this design wasn't firing on all cylinders, and as such having
four cylinders was really more of a burden to this design than it was an asset
because, at any given instance, one thread was lugging around another thread
because of blocking problems. You're right: the least of your blocking
problems was one MDI window sending a message to another. But that's only
because the rest of the design was so painfully poor.
> I personally think that a separate thread for each document view would be
workable
> in this case because the amount of user interaction (and therefore events
that
> would spawn MDI window management messages) is small compared to the actual
> amount of processing that was going on.
That can be true, but you're just making a system that uses an extreme access
pattern to justify a questionable design. If this system you've described is
using a thread per MDI child, it's poorly architected: it still sounds like
all of the UI should be in one thread and each printing operation and each
lookup operation should be handled by a thread from a small pool of threads.
The work that happens there should communicate with the UI when the UI has the
time.
> a number of times and when it does you dismiss it out of hand.
I'm still not really convinced, I'm afraid. I know that people can cook up
some pretty kooky things, and maybe someday someone will show me a situation
where a thread per MDI child is a design win. But, until then, I'll point out
to people that this design has never been a good idea in any situation ever
presented to me. From what I get from your description of this system, using
a thread per MDI child doesn't seem bad because it's just the least of all
sorts of swirling, nasty evil.
> btw: I enjoyed your article in May's MSJ.
Thanks.
> Do you have your hockey server running full time yet? Go Penguins!
No. I've dabbled around with it now and again, but the problem is that I have
a massive data entry problem. I would want to keep statistics at a very
detailed level (down to penalty calls, goal scoring times, and shots on goal
per player per period). I've gone through a couple of logical database
designs, and then realized that no matter what I did, data entry would take up
the rest of my life... assuming I could get permission from The Hockey News to
replicate their data, anyway.
.B ekiM
TCHAR sz[] = _T("Check twice and save a life: motorcycles are everywhere.");
John Addis -- jaddis@erols.com
Sunday, May 19, 1996
Mike Blaszczak wrote:
>
> ----------
> From: owner-mfc-l@netcom.com on behalf of John Addis
> Sent: Tuesday, May 14, 1996 08:09
>
> > This should give a fair picture of the system.
>
> I'm afraid I had a really hard time following you. I don't understand what
> part of this system ran on clients, and which ran on servers... if any at all.
> I'm assuming there was _some_ distributed processing going on, since you say
> that some machines had 4 CD drives and some had 10, but you had 2000-some
> CDs. That means that you had well more than 200-some machines, and they must
> have done some sort of cooperative processing. I couldn't infer who was
> creating threads on who's behalf and when.
I fear I was not clear enough in my explanation of the system. There were not
servers involved, nor was there any sort of distributed processing going on.
The entire collection of 2,000+ discs was not 'online' at the same time. Each
client site/machine had their own copy of some portion (possibly all) of the
entire collection. And nobody was creating threads -- it was (is) a 16-bit app.
> > Yes, right across process boundaries.
> > They also carelessly littered "PeekMessage" loops all over the damn place.
>
> I'm not sure where they're multitasking, or what at all they won (besides job
> security) for using multiple threads in this system. You've not presented me
> with a situation where one thread would free up and get work done while
> another would be blocking; you've implied that was happening with printing,
> but printing shouldn't involve an MDI child window.
I don't think that they had job security in mind as they all quit before the
project was finished.
As for a situation: document requests were not necessarily processed in the same
sequence that they were submitted. A very crude and primitive scheduler iterated
through the list of available discs trying to process whatever requests it could
at any given moment. Each "view" request created a new MDI child up to a preset
limit. The scheduler continued to run even when it couldn't possibly start any
new 'jobs' -- printer occupied and max views shown. A smarter scheduler could
have created a thread for each job, then waited for one of the jobs to terminate
before taking up any more CPU time.
> ... all sorts of swirling, nasty evil.
Well put. One would almost think that you had worked on the system.
btw: I was early for work on Wednesday. I'll see if I can schedule the same
for you. :-)
--
John Addis Master of Time and Space
jaddis@erols.com C++, MFC, Win32, Win95, TCP/IP
"Invalid or missing REALITY.COM Universe halted."
| Вернуться в корень Архива
|