(Almost) Everything You Read About Threading Is Wrong!
Threading is on the front pages more than ever, so to speak. Where only a few years ago programmers could brush the topic aside as complicated and not-very-useful, it’s increasingly harder to hide behind those excuses. Multi-core systems are the status quo and the only real way to get better performance (read: scale) is to have multi-threaded code.
So it’s no surprise that the topic is revived and there is more talk about it. And what threading if one doesn’t mention the pitfalls and problems? Consider the following question:
int x = 1;
int y = 0;
if (y == 0)
{
// Can x be anything but 1 at this point?
}There is no shortage of this type of questions. And there is no shortage of answers either!
The only correct answer to the above question is: It depends on the language!
What does the keyword volatile do? Same answer.
Does my code suffer from the ABA problem? Same answer (but that one is more complicated)
Similar question, same answer.
// Thread 1 x = 1; y = 0; // Thread 2 int a = x; int b = y; // if b == 0, is a == 1?
Here is a pdf presentation of a lock-free hashtable in Java. Here is the video presentation. Again, if the same algorithm implemented in a different language, the result will be different. Namely, it won’t work.
Why? Because the memory models are different. C++ has a very, very different memory model than .Net than Java. (It wouldn’t be entirely wrong to say that C/C++ don’t define any memory coherency models as such.) Each in their turn probably have a different memory model from other languages. And talking about threading without knowing the memory model is like assuming you can drive at the same speed on all roads. Well, some aren’t even paved, yet some have minimum speed.
It’s very unfortunate that an already complex subject is made even more confusing by the differences in languages and their guarantees, or lack thereof. There is no shortage of confused, misleading and downright incorrect information when it comes to threading. Consider that locks don’t even protect your code against out-of-order execution. But in which language is that?
This is made even more complicated by the fact that processors and hardware architectures come with their own set of guarantees and reservations. So reading on those without taking into account what the language in question abstracts from the hardware, is yet another way to throw oneself in the rabbit hole.
So, the next time you read (or write) about threading issues, make sure you know which language is in question. If it doesn’t say, stop reading. Without that small one-word detail, everything you learn is wrong, regardless of how detailed and coherent it is. Because precise doesn’t necessarily mean accurate.
From http://blog.ashodnakashian.com/2011/07/almost-everything-you-read-about-threading-is-wrong/
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Ronald Miura replied on Mon, 2011/07/11 - 1:39pm
Cosmin Mutu replied on Tue, 2011/07/12 - 7:34am
I thought I`ll be reading something interesting when I opened your article, but ... well ... shame on me for beeing fooled by the title.
Of course threading is dependent on the language. That`s why we have multi-processor parallelism and multi-threaded parallelism... one is using processes as the lowest unit of work (OS is the owner) the later one is using "thread" as the lowest unit of work (JVM is the owner in the case of JAVA).
Anyway, you should pick your titles better.
Ashod Nakashian replied on Tue, 2011/07/12 - 9:08am
in response to:
Cosmin Mutu
That's not as easy as it may seem. But back to your point, while it's obvious that "threading is dependent on the language" many developers working with multiple languages don't actually realize that what is thread-safe in one language is completely broken in another. The point isn't the dependency, rather that theory can't be applied blindly. A lock doesn't give the same guarantees equally in all languages. If you've worked with Java only, then you're lucky. Java has a pretty good memory model.
Cosmin Mutu replied on Thu, 2011/07/14 - 2:49am
in response to:
Ashod Nakashian
I agree with you. I also think that anyone who is using THREADS (or any form of parallelism) should first document himself a bit (if possible 2 bits).
"A lock doesn't give the same guarantees equally in all languages" ... this sounds interesting.
So you`re saying that the concept of lock, implemented correctly in two different languages is not doing what it should do? (Of course there are small differences, but I am talking about the main functionality, locking an object).
Well, if this is the case, then that language does not support "locking" or it has a poor support for synchronized units of work.
Also I would be very interested to learn about such a difference between two languages which are rather simmilar than different (for example, C, C#, Java, PHP).
Yup, I`ve only used JAVA for threading so far.
Ashod Nakashian replied on Fri, 2011/07/15 - 6:53am
in response to:
Cosmin Mutu
No. I'm saying they don't necessarily make the same guarantees.
For example, in some language a lock may guarantee a full memory-barrier, which ensures no reordering can take place. In addition, it may guarantee that all writes are flushed from CPU cache to main memory (which is shared between CPUs.) These aren't guarantees that all locks must make. As you can tell, the purpose of the lock is to ensure exclusive execution of a single thread at a time. The side-effects that I mentioned may be very welcome and useful, but they aren't necessarily part of the lock definition. So one shouldn't make assumptions across languages. Because while all locks should behave similarly, there are other nuances.
As a concrete example, consider that using locks isn't enough to have a thread-safe singleton. This pattern has been discussed ad nauseam. Here is in C++, in Java and in C#. The problem isn't in the lock, usage of locking or implementation. The problem is in memory models, compiler reordering and out-of-order execution.
To be fair, for most all this is academic talk that they wouldn't lose sleep over. And perhaps we shouldn't either. However the issues are real and do affect the stability and/or correctness of some applications, and therefore are of great importance to some.
Cosmin Mutu replied on Mon, 2011/07/25 - 7:40am
in response to:
Ashod Nakashian
Ok, your reasoning is fair enough,
I declare myself happy :)