The way I see it is that before C++11, the semantics of individual threading implementations relied on compiler and platform-specific primitives (like atomics and barriers) that happened to be similar enough to create an illusion that C++ supports multithreading as a language.
C++, for all intents and purposes, supported multithreading before C++11 via extensions and libraries that are vaguely similar to each other on different platforms, but you can never be sure that your multithreaded code will work when ported to another platform (see "volatile" keyword semantics in standard C++ as opposed to MSVC).
But now,
1. it's officially mandated, and
2. you have more tools in your concurrency toolbox (for example, compiler-independent atomic variables with the ability to fine-tune memory order).