Re: Threads - When?
Hi Joe,
Joe Seigh wrote:
Unfortunately, they seem to be concentrating on low level design
right now, specifically the memory model. The problem is they
don't know how to do high level specification so they're creating
a low level specification and will do the higher level constructs
in the form of a meta implementation.
What do you mean here? Are they concocting new low-level C++
primitives that presume the existence of hardware instructions to
support those new primitives?
It turns out that things
like deadlock are actually artifacts of implementation.
Implementation of the programmer's problem?
If so, I agree. Deadlock is an engineering (design) issue. If a
system deadlocks, it deadlocks because the programmer has constructed
the program in a manner in which it should not have been constructed.
The fundamental questions then become:
1. Was there a lack of in C++ or OS primitives that made deadlock
inevitable?
2. Was the use of those primitives improper?
3. Were the primitives present, but in a form that obscures the path to
good system structure?
It has been my experience that, at least on industrial strength
operating systems like Microsoft Windows, the problem is never #1.
Programmers who appreciate their art will learn what they need to know,
so often, the problem is not #2. The problem is most often #3. I
could go to Google right now and do a search on "thread class" and
"C++", and find a bunch of examples of people who have wrapped threads
in classes. I think this is the wrong approach. Wrong because there
is a certain mood that a programmer should when using any framework,
and that mood, IMO, is not achievable by wrapping a thread in a class.
That mood is, however, achievable by wrapping the _other_
synchronization primitives in classes.
IBM has written a series of excellent articles that show how to port
applications to Linux from Windows. Reading these articles helps to
convince oneself that there is a defect in our current expectations of
the thread function, considering many scenarios:
http://www.ibm.com/Search/?q=threading+mutex+Windows&v=14&lang=en&cc=us&en=utf&Search.x=0&Search.y=0&Search=Search
These synchronization primitives do not exist in a form that is
portable, of course, but at least on many industrial strength operating
systems, they are present. The only qualm I with Microsoft's Win32 API
for synchronization is the critical section. It is the only primitive
where it is impossible to wrap it in a truly portable (no #define's)
C++ wrapper facade. It's raw presentation is a Windows-native struct,
as opposed to a HANDLE which is actually a pointer type. All the other
primitives can be made more or less portable.
But again, what I learned by wrapping these primitives is that the
problem with synchronization has nothing to do with defects in C++. It
has to do with how one thinks about concurrent programming. In
particular, to find a regular framework for multi-threading, it helps
to make certain fundamental assumptions about the thread function. An
analogy would be a stack for recursion. One does not really need a
stack to do recursion, but the assumption and expectation that it is
available makes life easier, and no modern programmer would think of
using recursive functions on any other basis.
The same applies to threading. Do we need a breakthrough? No.
Modification in expectations? Yes. For threading to feel natural, we
need to have confidence knowing that complexity will remain constant no
matter how many threads or locked global objects we have. This is a
matter of elegance. Take a look at this link, and imagine having 80 or
so invocations of this function and its friends in one program (as I do
now), and ask yourself if you would feel confident that your code would
not deadlock.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/waitformultipleobjects.asp
I wouldn't.
There's
nothing inherent in locking that requires deadlock to happen. But
if your meta implementation can allow deadlock to occur then all
your actual lock implementations will be required to deadlock
under certain conditions.
What do you mean by this? :)
There might be a loophole where you could claim if the specification
has non-observable behavior, you could ignore it. But with the fondness
for post condition definitions in C++, they will likely make behavior that
is non-observable in a multi-threaded environment deterministically
observable in a single threaded environment.
And this?
-Le Chaud Lapin-
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]