C# Multithreading Book Recommendation

R

Robert Zurer

Can anyone suggest the best book or part of a book on this subject. I'm
looking for an in-depth treatment with examples in C#

TIA


Robert Zurer
(e-mail address removed)
 
M

Mountain Bikn' Guy

There doesn't seem to be a book like this. I've been looking for the same
thing.
 
A

Alvin Bruney

No no, there are several. I have a book recommendation section on my website
if you want to get a quick heads up, but basically if you want to know
threads intimately you must get Richters book. You should have it anyway. In
addition, there is a lot of threading material covered in mathew macdonald's
book on remoting. These two books together demystify threads. At least, you
get the theory right on what you are supposed to do, then you get to spend
another 10 years learning how to master it. It really does take that long,
anybody tell you differently, they're just trying to sell you something.
 
M

Mountain Bikn' Guy

Alvin,
Thanks for the info. I know about Richter's book. It has gotten really good
reviews on Amazon. I also like MacDonald's writing. I guess I jumped to a
false conclusion regarding what the OP seemed to be asking for. I assumed he
wanted what I want -- a COMPLETE book devoted just to .NET threading (using
C# examples). We have complete books for Win32 and C/C++ threading, so why
not a complete book for .NET/C#? I'm still looking for it...
Regards,
Mountain

P.S. In my opinion (worth 2 cents), using .NET well, together with an
architectural-level state machine approach, one could have the equivalent
level of performance and reliability in their finished code as a 10 year+
threading master -- and in short order.
 
A

Alvin Bruney

I'm looking for that book as well. Let me know when you find it, especially
one geared toward asp.net since the object model is different and some
threading rules either are different or don't apply entirely.
 
M

Mountain Bikn' Guy

BTW, I should also have qualified my statement even further:
"I want a really good complete book devoted just to .NET threading (using
C# examples)."

If I didn't add that qualification ("realy good"), I'm sure someone would
point me to a book like ".NET Multithreading"
by Alan L. Dennis (or one of a couple other similar titles). (No offense
meant to the author, but the reviews of this book on Amazon make it sound
like a book I would not be willing purchase -- therefore I don't count it
amoung my options in the search for a good .NET threading book.)
 
J

Jon Skeet [C# MVP]

Mountain Bikn' Guy said:
P.S. In my opinion (worth 2 cents), using .NET well, together with an
architectural-level state machine approach, one could have the equivalent
level of performance and reliability in their finished code as a 10 year+
threading master -- and in short order.

I have to quibble with that - while I'm not sure about Alvin's 10 year+
quote, unless you understand the specific threading model of whatever
you're coding against, you *will* run the risk of reliability problems
- perhaps not on today's hardware, but on hardware which might have a
CLR implementation which is closer to the limits of the specified
memory model. It would be easy to make mistakes like the double-checked
locking algorithm which doesn't work in .NET, but for subtle reasons.
 
M

Mountain Bikn' Guy

Jon Skeet said:
I have to quibble with that - while I'm not sure about Alvin's 10 year+
quote, unless you understand the specific threading model of whatever
you're coding against, you *will* run the risk of reliability problems
- perhaps not on today's hardware, but on hardware which might have a
CLR implementation which is closer to the limits of the specified
memory model. It would be easy to make mistakes like the double-checked
locking algorithm which doesn't work in .NET, but for subtle reasons.

My statement was expressing my hope more than any factual reasoning.
However, this hope isn't based purely on wishful thinking. My own gameplan
is to use a bit of a paradigm shift. The best way to solve any problem is to
rise above the level of the problem. I feel most (all) threading problems
can be avoided at their source via a change in software development style
(i.e., architecture). For example, see
(http://www.quantum-leaps.com/com/qfplus.htm) and note this quote:
"An application running on QF+ is guaranteed to be free of multi-thread
problems." The Quantum Programming paradigm may not be everyone's cup of
tea, but I have no doubt the tools and knowledge are available to allow me
to master multi-threading issues in much less than 10+ years.
 
J

Jon Skeet [C# MVP]

Mountain Bikn' Guy said:
My statement was expressing my hope more than any factual reasoning.
However, this hope isn't based purely on wishful thinking. My own gameplan
is to use a bit of a paradigm shift. The best way to solve any problem is to
rise above the level of the problem. I feel most (all) threading problems
can be avoided at their source via a change in software development style
(i.e., architecture). For example, see
(http://www.quantum-leaps.com/com/qfplus.htm) and note this quote:
"An application running on QF+ is guaranteed to be free of multi-thread
problems." The Quantum Programming paradigm may not be everyone's cup of
tea, but I have no doubt the tools and knowledge are available to allow me
to master multi-threading issues in much less than 10+ years.

That may well be appropriate in some situations - and where it is,
that's great. I don't think it will solve *all* problems by a long
chalk, however, and from the little it says on that single page (which
is all I've looked at) it wouldn't scale well for various things which
really *require* more than one thing to be going on at a time.
 
M

Mountain Bikn' Guy

Jon Skeet said:
That may well be appropriate in some situations - and where it is,
that's great. I don't think it will solve *all* problems by a long
chalk, however, and from the little it says on that single page (which
is all I've looked at) it wouldn't scale well for various things which
really *require* more than one thing to be going on at a time.

Jon,
I don't expect you or anyone else to agree with me on this, but my opinion
(reflecting the paradigm shift I mentioned) is that Quantum Programming (or
an approach like it) will solve most problems better than today's OOP. It
may not solve all problems -- but I don't guess any single approach ever
will. However, there is the traditional approach to multi-threading, which
is filled with pitfalls. And then there are better approaches. I believe
Quantum Programming ("QP") is one of those better approaches.

QP includes the concept of active object computing. Here's an explanation
from the web site list above:

"Perhaps the most important characteristics of active object-based computing
model is that individual active objects can be programmed internally with
purely sequential techniques thus avoiding most of the hazards of
traditional multithreading (such as race conditions, deadlock, starvation,
or priority inversion). Yet, an active object application (as a whole) can
reap all the benefits of concurrent programming, such as fast task-level
response, good CPU utilization, and scalability."

I personally have no doubt that this approach will scale better than most
approaches commonly in use today. A similar technique is part of the
patented technology of Z-force (http://www.z-force.com/) and an
investigation of their accomplishments should put any scalability doubts to
rest -- actually, that's an understatement. Traditional approaches can not
match the scalability of an approach like the one I'm discussing.

Regards,
Mountain
 
A

Alvin Bruney

on hardware which might have a
CLR implementation which is closer to the limits of the specified
memory model. It would be easy to make mistakes like the double-checked
locking algorithm which doesn't work in .NET, but for subtle reasons.

That is exactly my point. You can't come across this information over night.
It takes years to get to know the intracacies well so that you can thread
efficiently. I don't suppose either that you came across that information
overnight, or you read it in a book? It probably came from elbow grease and
wrong turns - the stuff experience is made of.

That's the point i'm making. Sure you can thread an application and have it
work reasonably well, but do you understand what's going on underneath the
hood by reading a book? No. Then how can you squeeze performance from said
app? It's gonna take about 10 years. And that's optimistic estimating.
 
A

Alvin Bruney

I disagree with that (i'm in the process of reading the page but i thought i
would get this out first). Some problem domain solutions require requests be
processed simultaneously if not for scalability, certainly for efficiency
reasons. How does QF address these?

It is fundamental to have the ability to process simultaneously, so how can
you refactor or re-architecture to speed up response if you are limited to a
queued approach? As an example, consider a webserver receiving requests. For
efficiency and scalability, these requests must be handled simultaneously.
How does QF address this? What kind of architecting can you do to improve
this situation since you are necessarily limited to a single thread?
 
M

Mountain Bikn' Guy

One is absolutely not limited to a single thread in an approach like this.
Z-force, for example, uses what I'll call a "hyper-multi-threading" approach
(although that isn't the terminology they use). Their performance proves
that this type of approach scales better than anything else out there. And
that's just one example.
Mountain
 
J

Jon Skeet [C# MVP]

on hardware which might have a

That is exactly my point. You can't come across this information over night.
It takes years to get to know the intracacies well so that you can thread
efficiently. I don't suppose either that you came across that information
overnight, or you read it in a book? It probably came from elbow grease and
wrong turns - the stuff experience is made of.

That's the point i'm making. Sure you can thread an application and have it
work reasonably well, but do you understand what's going on underneath the
hood by reading a book? No. Then how can you squeeze performance from said
app? It's gonna take about 10 years. And that's optimistic estimating.

I never said it was easy - but I *do* think that 10 years is an
overestimate. For instance, Java is not yet 10 years old - do you
believe there are no experts in Java multi-threading?
 
A

Alvin Bruney

What is your *estimate? For an average man of average intelligence. Sure
everything is dependent on something but what do you think is a good ball
park if you think 10 years is on the high side
 
J

Jon Skeet [C# MVP]

What is your *estimate? For an average man of average intelligence. Sure
everything is dependent on something but what do you think is a good ball
park if you think 10 years is on the high side

It really depends on how much of your time is spent explicitly doing MT
stuff. I learned an awful lot during one month where I was trying to
sort out the threading policy for a particularly messy bit of code. I
already had a fair amount of experience before that.

If you really immersed yourself in it (not just theory, but practical
applications) I'd say you could do pretty well in 6 months to a year.
If it's more occasional, but still regular (if you see what I mean)
then 5 years is more realistic. That's not to get to expert level, but
to get to the stage where you can get it right almost all the time,
even if it's not as efficient as it might be in the hands of an expert.
 
M

Mountain Bikn' Guy

Serial Event Processing or RTC (run to completion) is not the same as a lack
of multi-threading. I think this point may have been misunderstood from my
earlier post. Here's a bit more info... it's a moderately short excerpt from
a 1997 paper... you have to read down a bit to get to the description of
"actors", which is one half of the foundation of Quantum Programming. QP is
founded on the 2 fundamental concepts of hierarchical state machines and
active object-based computing.

The Vision
Multi-threading Without Headaches
Conventional Approach
It is generally acknowledged today that multithreading applications or
agents confers
many benefits: improved scalability, improved responsiveness to external
stimuli,
improved modularity, and so forth. The question before us is not whether
multithreading
is desirable, but rather how best to introduce multithreading within an
application as well
as effect communication and synchronization between threads.
The general practice in this regard - sometimes called free threading -- is
ad-hoc,
proceeding largely as follows. A multiplicity of threads are spawned, each
anchored at an
associated object (e.g. communication socket, timer, console event loop, a
semaphore)
where they each block pending an event (UDP packet, time-out, mouse event,
semaphore signal(), respectively). Once awakened a thread will typically
course through
a mesh of objects, entering each by invocation of a class method according
to the
operation to be performed. This chain reaction may be suspended for a time,
due to
preemption by another thread, or pending completion of some action, a
time-out, etc.
Finally, having completed all processing, the thread withdraws back to its
lair where it
resumes its vigil for fresh stimuli.
There are many problems with this and other related approaches:
* Race-conditions: special precautions much be taken to avoid
race-conditions
when two threads collide on the same object.
* Deadlock: the previous problem is typically averted through the use of
mutex
semaphores. This practice may give rise to deadlock (or worse yet, unwanted
reentrancy)
should a thread, over the course of its wanderings, loop back in a cycle
to an object through which is already threaded.
* Architectural Constraints: the need for deadlock avoidance may require the
needless imposition of strictly layered architectures that preclude cyclic
threading, thereby limiting the range of options open to a designer.
* Non-determinism: unless one knows in advance the maximum span of time a
thread may spend traversing a mesh of objects, other threads may be locked
out, for indeterminate periods, of objects on their path currently threaded
by
another thread.
* Complexity: Averting the previous problems may require careful
partitioning of
the object space among threads responsible for their animation, a judicious
assignment of thread priorities, and the introduction of inter-thread
synchronization and communication primitives as needed to effect changes
across partition boundaries. Regrettably, the miscellaneous instruments used
for
this purpose, such as counting and mutex semaphores, message queues,
monitors -- the pins and needles of the system programmer's subtle craft
should not be entrusted to the use of a typical application programmer, lest
subtle intermittent faults be introduced into the workings of a system,
faults
notoriously hard to reproduce, isolate and correct.

Actor Based Multithreading
For these and other reasons the distributed operating system community
(which
encountered problems very similar to those listed above while building
scalable network
operating systems) has been gravitating toward micro-kernel architectures. A
microkernel
Operating System is built on top of a small message-passing nucleus by
addition
of light-weight threaded concurrent server components that communicate with
one
another and their application level clients through message passing. In
particular, use of
message-passing implies, in theory at least, that components need not be
co-located in
the same host to communicate.
When this message-passing model is applied to the realm of objects it yields
the notion of
actors: active event driven objects endowed with a locus of control. While
it is certainly
true that counting semaphores, mutexes, monitors will serve most honorably
in the
construction of an Actor Framework, base actor classes and the
message-passing
apparatus, these often troublesome instruments need not be used by
application
programmers directly.
The most salient characteristics of actor-based multithreading are these:
* Serial Event Processing: Actors process one event at a time, to
completion,
according to a prescribed event scheduling discipline (e.g. priority/FIFO,
Actor
receptivity).
* Atomic Event Processing: Event processing is atomic, that us to say
indivisible
and instantaneous at a logical level. Accordingly, application level
critical sections can
be avoided through the introduction of a server actor responsible for a
shared
resource or service, together with an associated service protocol.
* Asynchronous Event Processing: Regardless of the scheduling model that is
employed (e.g. free or partitioned threading or both) an actor can view all
messageborne
interactions with its peers as occurring asynchronously. Towards this end,
incoming messages are automatically queued within the target actor should it
be
"busy" (i.e. already threaded), or mapped to another thread partition, this
without
need of any involvement by application programmers. Thus whenever a request
message is sent to from one actor to another, any response message that
might be
forthcoming will be subject to processing in due time. Should the response
reach the
service requester while it lingers still in a transaction - perhaps the very
transaction
that evinced the response -- the response is simply queued for subsequent
service,
at the first opportune moment. In this way deadlocks are avoided and
designers
regain the architectural license to build as they see fit, untrammeled by ar
bitrary
layering restrictions.

All Rights Reserved © 1997 Charis Software Systems, Inc.

The whole paper is available from the links I provided in my earlier post.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top