views:

391

answers:

8

Why is it that threads were never included as part of the C++ standard originally? Did they not exist when C++ standard was first created?

A: 

Because the authors didn't want to force a particular behaviour on implementers.

Oli Charlesworth
And why do "they" want to do it now? I bet that, had there been a good threading proposal in 1994, we'd have standardized threads now.
sbi
And I'd bet that it would be as popular as `iostream` and its abuse of shift operators.
Mike DeSimone
@Mike: A heartfelt `:)` for the ["abuse"](http://stackoverflow.com/questions/3626483/need-some-kind-of-operator-c/3626541#3626541).
sbi
A: 

Because they are OS dependent. I.E. unix/linux/macosx use pthread API, Windows use its own API, and so on and so forth...

They could have been included into libstdc++, but I guess it is not easy to include all current and future thread features on a common API. The same way, DB access is not included in libstdc++ either.

Pablo Santa Cruz
You mean each OS creates them differently?
Tony
They treat them differently, and they have a different feature set. I.E., POSIX threads do not have fiberthreads, whereas Windows threads do.
Pablo Santa Cruz
So what? Files systems differ, too, but we do have file streams nevertheless.
sbi
A: 

Threads are an OS thing, so they aren't really a function of the programming language as much as they are the libraries provided by the system. POSIX threads for example, can be used in C++ but aren't really "part" of it.

SubSevn
They really do require help from language standards, though -- which is why "C++0x" (as it was called) is adding a memory model. Threads really can't be implemented purely as a library.
SamB
If that was right, why do have so many other programming languages threads? And why will we have them in the next C++ standard?
sbi
Perhaps I should clarify, not "libraries" provided by the OS, but more "services provided by the OS", since the programming language has no idea whether or not the OS even supports threading.
SubSevn
The fundamental conflict is that languages describe processing flow, OSes implement it via things like the process model, and trying to fence threading into libraries would overly limit them. There are significant benefits from both OS and language support of threading. For example, the OS can optimize scheduling, and a language can analyze threaded code to hint to the OS on how to optimize. Maybe an OS can optimize a thread if it knows that thread doesn't use file I/O or malloc/free, or if there's a dispatch point in the code that is best implemented with a thread pool.
Mike DeSimone
+12  A: 

The current Standard is from 1998. There were different thread implementations, and there wasn't the body of experience with using threads that there is twelve years later. If C++ had had a standardized thread library, it would likely have worked poorly with some common thread implementations, and might well have been difficult to adapt in the future.

It's twelve years later now, and we know a whole lot more about how threads are used, and the more widespread use created more interest in standardizing them, so the upcoming C++ standard (which I hope will be official in 2011) will have a section on threads in the library.

David Thornley
+1 - this is not a "threads depend on the OS", it's for historical reasons
Steve Townsend
Actually the current standard is from 1998 (although it was pretty fixed already a year before that.), with a few additions, clarifications, and fixes (TR1) from 2003. There was a lot known about threads back then, there even had been C++ threading libraries. It's just that C++ isn't company-driven, and if no one picks up the work lying around, it isn't done. IIRC, the threading efforts for C++1x (currently expected next year) didn't start very early either. But finally a few people picked up the work and came up with a few proposals decent enough to be a base for discussions.
sbi
I disagree that 15 years has added a lot to our knowledge of threads or how to use them. All the major components for threading were around and have not changed much in the last 15 years. The difference now is that the ability to use threads (multi-core and multi-processor architectures are common) is more mainstream and thus we have more emphasis on the need to standardize them (and make them easy to use for Joe beginner (IMHO that's not a good idea as Joe is still going to screw no matter how much we try and protect him)).
Martin York
@Martin: I agree that Joe beginner and multi-threading don't work together. MT is hard to reason about, for everyone, and harder to test. However, the use of `future` (for example) does encapsulate much of the threading logic and make *some* MT usages available to all.
Matthieu M.
@sbi: Thanks for pointing out the year error. I fixed it. Also, I really meant that we know more about how threads are used, so thanks for pointing out my lack of clarity.
David Thornley
@Martin: Yes, I forgot that. Thanks for reminding me; it's now in my answer.
David Thornley
But what if I want Novell Netware threads, heheh?
Eric M
+3  A: 

Threads certainly did exist when C++ was being standardised during the 1990s. However, Windows and Posix have very different threading APIs. Designing a library of the quality you'd want from a standard language library, giving all the threading primitives you need and mapping well onto both popular APIs (and others), required a large effort. Including it in the initial standard would have required either delaying standardisation, possibly for years, or including a specification that may well have had significant shortcomings.

That work has been done over the last decade or so (initially as the Boost.Thread library), and will be included as the standard thread support library in the next version of the standard, in addition to language-level features such as thread-local storage.

Mike Seymour
+11  A: 

I think the main reasons are

  • specifying threading behavior into the language needs a lot of work and understanding, which nobody had available back then
  • nobody had a great idea about a good threading API, and there was no one existing library that seemed good enough to be used as a base for further work
  • the standardization committee was swamped with enough of other work (like incorporating the STL into the standard library)
  • that standard was late as it was; it took more than ten years for the first version to emerge, with quite a lot delay due to "last-minute changes" (std::auto_ptr, STL), and I think the main feeling was to better have something out sooner than to keep waiting for an infinitively delayed perfect standard; I think back then most people didn't think it would take so long for the next version to get finalized

After the standard was ratified, boost was founded by members of the library working group as a testbed for libraries which were desirable to have in the std lib but for which there wasn't enough time to make it for the final version. There, much of the work needed for adding threading support to C++ (namely inventing a good threading library) was done.

sbi
I always enjoy reading your comments and answers. :) +1, good answer
Default
@Default: I'm flattered. `:)`
sbi
+1  A: 

There is a lot of work involved in creating a thread class and C++0x has largely addressed this by adding the thread, mutex and atomic libraries but it took a lot of work from a lot of folks.

Orginazationally, remember that C++ is a very large language and changes happen quite slowly to it because of the complexity of the language and the amount of code and industry that rely on it; it takes a long time to get ratify changes into the standard because of this.

Also threading and synchronization has typically been an OS provided functionality so any additions needed to be compatible with the common implementations and possible without massive changes to the platforms (or noone would be able to implement the standard).

Technically, it isn't sufficient to just add a thread API, C++ was also missing a cohesive memory model, i.e. how do variables interact across thread and how do we allow for the wide range of memory models to be expressed in code succinctly (and performantly). Most of us are fortunate enough to work on primarily single-threaded x86 based software which has a very forgiving memory model, but there is other hardware out there that is not as forgiving from a memory model perspective and where performance penalties can be quite harsh.

The library addresses the memory model issue by providing atomic variables with forgiving defaults and explicit control.

The library provides another key piece of functionality for portable threading by providing synchronization classes.

Finally was added and if you haven't read the history on the working group site, it's interesting, but simply replacing CreateThread, QueueUserWorkItem or a pthread invocation was a thread object isn't quite enough. Thread lifetime, state management and thread local storage all had to be thought through.

All of this took a long time to get right and as others have mentioned most of it was in boost for quite awhile to ensure that major issues were worked through and it was cohesive before making it into the new standard.

Rick
A: 

One of the challenges that was faced by the standard committee 12 years ago is the differences in the parallel hardware. A key distinguishing feature between various high performance computing architectures is the way the permit parallel computation, and only one of those many models is really similar to the posix threads abstraction, SMP.

If you compare this situation to the one faced by the Fortran language, which targets this sort of hardware specifically, you see that each vendor supplies a Fortran compiler that they have extended to support the special parallel computing features the hardware provides.

This can be seen as relevant in todays terms by comparing typical x86/x64 white box compute nodes, which usually have up to 4 sockets, which translates into 24 cores with a single shared memory to a Gaming PC with multiple nVidia or AMD GPU's. Both are capable of startling compute throughput, but to get the most out of either requires a very different programming style. In fact, different workloads will work significantly better on one architecture than the other, depending on the exact nature of the specific algorithm.

That being said, it was probably impossible, 12 years ago, for the standard committee to identify how it should address each of these issues. Now, however, the answer is much simpler. C++ is not aimed at anything besides SMP hardware; those are served by other languages and tool-chains such as OpenCL or VHDL.

TokenMacGuy