Multi-threaded Programming Makes You Crazy?
gduranceau writes "Help! My program deadlocks! I got several concurrent threads that write the same variable! Everything goes well on my mono processor but becomes an incredible mess on that 16 CPU monster! And of course, as soon as I add traces, problems disappear... Don't panic! Calm down and take a deep breath. "
Oh wait. I was supposed to praise the NPTL tool, wasn't I. Um... well... it's very nice. And they've got... um... penguins on the homepage. Oh, and look! It's GPLed! Wow. Just... um... wow. Hey, did you know that the author of Minix wrote a book on OS Design? Really. It even covers the basics of multi-threading. It's pretty cool, you should... um... check it out. Yeah, that's the ticket!
Javascript + Nintendo DSi = DSiCade
Are a little mad anyway ;)
Our greatest enemy is neither a single man, nor is it a nation, it is, as it has always been, our own greed.
No, this title does. Is a Sentence? Is a Question? Why There a Space Before the Question Mark? What 'Programmation'?
I was wondering what was this program was about. Fortunately, here is there website. http://nptltracetool.sourceforge.net/
Ooo man the floppy drive is broken. No wait. The computer is just upside down.
Slashvertismentation.
These words are fillers.
Useful information? On slashdot? You must be new here.
Looking at the list of functions that it hooks into, I don't see pthread_rwlock*. Are the pthread_rwlock functions implemented using other pthread_* funcs? I haven't run into any problems yet with the project I'm working on, but it would be nice to run through this and make sure everything's working as expected.
<xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
...what's so original about this issue, that deserves to be posted to Slashdot? There isn't even a FA! If the guy wanted to publicize his work (he is a developer for the linked SF project), he could at least have written an article with a concrete problem (even if the problem was made up in order to show the solution), not just some generic rant about how tricky multithreaded "programmation" is.
You can probably get a better idea of the purpose of the program on their home page (click the link in the menu of the sourceforge page that says, "Home Page").
Not sure why they didn't link directly to it?
Java's "builtin thread saftey" is simply a poor hack. The idea is to give _every_ structure a mutex. Any access to the structure requires a mutex lock.
First off, that in itself will not prevent deadlock. Secondly, it's damned inefficient.
Look: there's just no way around it. If you want to do effective (i.e. low bug, high performance) multithreaded programming, you simply have to understand what you're doing. Ultimately, the tools of your trade will be mutexes, condition variables, semaphores, etc -- the O/S primitives. Don't rely on your programming language to "automatically" use these for you, blasting out mutexes machinegun-style. Instead, figure out the logic of your program. You probably need only a small number of mutexes.
A key to effective multithreaded programming is to adhere rigidly to certain programming practices. It must _NEVER_ be the case that 2 threads have write access to a given item at the same time. Duh. But you can use fancy programming tricks to, in effect, automatically add run-time assertions to your code which assure that this practice is being adhered to. In production mode, you remove these runtime assertions.
Another good practice is, if you really need to have multiple mutexes, to arrange them into a hierarchy. When a top-level mutex is locked, no other mutex can be locked. When a second-level mutex is locked, only top-level mutexes can be locked. Etc. This hierarchy can be verified at runtime, in debug mode. Adhering to this regime will go a long way to removing the possibility for deadlocks.
Bottom line: you really have to know what you're doing in order to write good multi-threaded code. You should take the time to really study that problem space. An excellent book I've found for this purpose is "Concurrent Programming in ML". (I know -- nobody uses ML. So what? Learn the language just for the purpose of understanding the book. Then, you can apply your knowledge to any domain you're working in).
Aha, so I can only do multithreaded programming on GNU/Linux with NPTL'ed glibc or what? Other programming langunguages than C/C++ don't exist or don't do threading. What about other operating systems? Specific solutions to general problems only apply to specific manifestations of the general problem and are therefore useless for most of us.
The only good general advice about learning how to develop software on distributed systems I can give is: Read some of Andrew S Tanenbaum's books about operating systems and distributed systems in particular. The books contain knowledge you'll be able to apply to almost every system you develop software for.
Developing multithreaded is infact difficult, and any tool claiming to make it easier is worth looking at. If it works, these guys have done us all a favor. If it doesn't, at least they've made an attempt, and it may inspire others to do improve on it. Better tools are always welcome.
Generally, bash is superior to python in those environments where python is not installed.
If you reply, do so only to what I explicitly wrote. If I didn't write it, don't assume or infer it.
http://valgrind.org/ used to include a tool called hellgrind for finding just such problems. unfortunately, hellgrind has gone away for a bit (it broke when the VM was re-done to support non-x86 platforms), but julian & co are working hard to get it working again Real Soon Now (tm). if you're using x86, you can use an old release of valgrind (2.2.0 i think) and you should be fine.
personally, i can't say enough good things about valgrind. there are a couple non-obvious issues (support for sse/sse2/sse3 is still in the works, so if you get an inexplicable SIGILL, this is probably the problem), but it's saved me hundreds of hours over the past year (and i'm sure it'll save me even more in the future).
that all said, my (admittedly limited) experience with threading is that it's best to design the deadlocks away before you even touch the editor. i wonder if there are any design tools which support deadlock / contention checking at the model or design level?
Realized that link wasn't as helpful as I remembered. But here are some other good general links that should get you going.
p df
http://en.wikipedia.org/wiki/Concurrent_computing
http://en.wikipedia.org/wiki/Message_passing
http://en.wikipedia.org/wiki/Actor_model
The E lang has some good documentation on concurrency, even if you don't use it.
http://www.erights.org/elib/concurrency/
As does Erlang.
http://www.erlang.org/download/erlang-book-part1.
"It is better to die on one's feet than to live on one's knees." - Albert Camus
that all said, my (admittedly limited) experience with threading is that it's best to design the deadlocks away before you even touch the editor.
That's not "limited" experience. That's common sense. Trying to find deadlocks, race conditions, and accidental serialization in an application by experimentally compiling and running is like trying to build a house by nailing the boards together only after they've collapsed on you.
Seriously, threads cannot be bolted on as an afterthought. You have to consciously design threads in in the first place, and if you ignore this advise and attempt to retrofit your code, then you must audit the code fully first to see where execution can be grouped into the smallest safe units for locking.
I've seen what happens when you ad hoc threading in large library that was never designed to be reentrant. Worse, I've seen what happens when you get it working on Windows but fail to realize that the UNIX version never was successfully locking the library for 3-4 years before a customer tried to build an aggressively multithreaded app on top of it and only then discover all the deadlocks that lay hidden inside.
If it's for-profit but free, you're not the customer -- you're the product (e.g., the Slashdot Beta's "audience").
Yes, there is a real reason. Sometimes it's inherent in the algorithm that the amount of data that must be shared is impractical to send using messages. Parallelization does not come for free; there are communication costs. If the communication costs are greater than the benefit you get from doing the computation in parallel, then you get no benefit from parallelization. Message passing will always have more overhead than shared memory multithreading. Hence, shared memory multithreading allows you to exploit finer grain parallelism than message passing.
Your point that message passing is generally a cleaner design choice is valid, but it's not always a practical option.
Slashdot reported the summary line thusly:
Developers: Multi-threaded Programming Makes You Crazy? 79 of 78 comments
What's wrong with this picture?
Firstly, I apologize for my English (I'm doing my best).
I perfectly agree with some of you: this article is a slashvertisment! The main reason for that is that I previously tried to submit something more descriptive, but it was rejected. That's why I tried again with a slightly different style.
This tool (PTT) inserts trace points into the NPTL to help you to analyze multithreaded applications behaviour. He's not designed for beginners, but for people facing complex multithreaded issues. I also agree with some of you: you can use Java or some others high level languages for programming. But some applications require performance and have to be written in C. That's why PTT can be useful for some developers.
PTT has been presented at the Ottawa Linux Symposium last summer. You can find the paper here (NPTL Stabilization Project, page 111).Regards...
A debugger won't help you if you're trying to ensure correctness at too low a level of abstraction. Most languages give you a couple of low-level building blocks equivalent to the pthreads basics: threads, mutexes, and condition variables. These should not be used directly except in the simplest of circumstances. Rather, they should be used to create a set of higher-level tools that can be applied in a simple and straightforward way to your task.
The most popular way is to create a workflow model with task queues, worker threads, and job dependencies, plus a few application-specific rules to ensure that resource limitations don't cause deadlock.
The high-level model can typically be lifted right out of your proof of deadlock avoidance. Don't have one of those? It's a good idea. The proof gives you a minimal solution and confidence to implement it. Without the proof, you're going to overkill the problem out of nervousness, and you still might miss something crucial.