15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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."





| Вернуться в корень Архива |