Re: Threads - When?
James Kanze wrote:
Le Chaud Lapin wrote:
Lourens Veen wrote:
The problem is not whether it will work or not, the problem is that
there is currently no way of writing a (guaranteed) portable C++
programme that uses threads. Currently, anything to do with threads
is undefined behaviour.
And IMO, that is the fault of the OS people and library writers, not
the language proper.
If the language says its undefined, no one else can make it
portably defined.
Let's take two simple cases from real life:
G++ (like everyone else, I think) uses objects with static
lifetime in its exception handling. Before 3.0, it used them in
such a way that if two threads raised an exception at the same
time, the exception object was corrupted. Please explain how
this is the fault of the OS people and library writers.
The person who wrote that part of the G++ library probably expected it
to be used in a single-thread application. If it had been intended to
be used in a multi-threaded application, the library writer should have
written it for multi-threaded applications. If he did not write a
multi-threaded version, then that is the fault of the library writer.
If I write a program that contains 10 threads, and they all invoke
operator new() simultaneously, and cause the heap to become corrupted,
that will be either my fault, or the library writer's fault. If I am
using the single-threaded library to call against the heap, it will be
my fault. If I am using the multi-threaded library to call against the
heap, and it still happens, then it will be the library writer's fault.
If I am doing what I do today, calling the multi-threaded version in a
multi-threaded application without incident, then there is no fault.
Also g++ pre-3.0: every constructor of std::string modified
(incremented, and often later decremented) a single global
counter object. You don't really expect users to use an
explicit lock everytime they construct a string, do you? Of
course, you might consider this a library issue, and not a
language issue, but std::string is defined in the C++ standard,
as part of the language.
Library issue. I have a string class too. It does not have this
problem.
There is a programmer currently writing a very nice Big Integer class
that I would hope would someday become part of the problem. Two weeks
ago, he stated, "I am going to get rid of static dependencies so that
it can be thread-safe." So he knows.
(BTW, the first time someone told me that STL was doing this (in
several places), what you mentioned above, I was appalled. He also
said there were similar issues with the standard containers.)
But adding such statements would be a change. In fact, analysis
has shown that the sequence point model doesn't adapt at all to
a multithreaded context. So a major part of the definition of
expression semantics, and what is or is not conforming, will
change.
Statements or library functions? Note that is entirely conceivable
that, at the end of the day, the code that uses "standard" C++
multi-threading support by way of libraries does not have much visual
distinction from that which supports by way of added keywords. The
thesis of what I am saying, that it is my opinion, based on my own
experience, that changes to the language are not necessary, any more
than it is necessary to change the language to grab random numbers from
the architecture, for example.
Threading is an issue at all levels. The OS can provide the
best primitives in the world, but if your code misuses them,
it's all for naught. At the lowest level, threading is a
hardware issue---if hardware does speculative loads, and pushes
loads forward (as modern hardware does), and doesn't provide the
necessary fence or membar instructions to inhibite this behavior
on command, there's no way an OS can offer the necessary
primitives. But of course, the OS has to play its part; you
don't want to have to implement all of the primitives in each
application,
You cannot implement them in the application. They have to be part of
the harware/OS environment. There is no programmer in the world who is
going to wield any type of magic to implement atomicity if it is not
already present in the hardware infrastructure. Incidentally, I spoke
to a friend who helps design the Power microprocessors for IBM to
confirm this this morning (random back-off tricks notwithstanding).
and typically, you probably can't, because some
things will require privileged mode. After that, the compiler
has to ensure that these primitives are actually available to
you, and that it doesn't automatically do anything forbidden in
the generated code. Intel processors have very few registers,
and so often have to spill in complex expressions. If the
compiler spills to static memory, it doesn't matter what the
processor and the OS offers. And of course, having a *standard*
interface, defined in the standard library, certainly helps
portability.
???? Spill to static memory? What about the stack? Even Microsoft
publish the rules governing the use of registers for their compilers.
I have been writing assembly language on Intel platforms since the
8088. I have never known any programmer to go to static memory because
of the paucity of register space, unless it was a situation where it
was conceptually appropriate to do so (frame buffer operations).
Needless to say, those functions would not be entrant, but no one would
expect them to be.
If compilers do this, they obviate recursion, in both trivial and
non-trivial cases.
None of which, of course, means that the programmer can ignore
the issues, and not pay attention to threads. All it means is
that when I write a program, I only have to analyse its thread
safety once, against the standard guarantees, rather than for
each platform, against the guarantees given by that platform.
I do sympathize with the "mood" that you seek. I am 100% in agreement
with having the programmer feel good while using the primitives for
multi-threading Again, I think that "feel good" can be achieved
entirely using libraries without perturbations to the language itself.
From where do you get this feeling? My impression is just the
opposite, that there is an enormous resistance to adding any new
keywords for threading; that no one wants any new keywords for
thread support.
Well, that makes me feel a lot better.
I get the feeling from what others have been writing about CSP,
efficiencies, or lack there-of with blocking, how it is bad that two
threads operating against an unprotected global variable can cause that
global variable to become corrupt...??? Isn't this obvious????
The last complaint is particularly important. It gives the impression
that, if the problem is being complained about, then those who are
doing the complaining do not know what is the solution. Otherwise,
they would not be complaining. And if they do not know the solution,
they are not yet aware that these problems can be easily fixed using
existing primitives (libraries) that are entirely orthogonal to the
language itself (as is my opinion and that of others). And if they
complain in the context of c++.moderated, there is the impression that,
not only are libraries not enough, something more must be done with
C++. But if the libraries are not enough, the only thing left to be
done with C++ is to change the language itself.
-Le Chaud Lapin-
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]