Hacker News new | past | comments | ask | show | jobs | submit login

Good article but I think it falls into the same trap that all 'smart people' (read: experts) do. I write multi-threaded embedded code in C for a living. It's hard - But it's not that hard... But that's because I do it for a living ALL THE TIME. If someone has a passing need for this kind of thing I don't think the arguments in the article hold water.

For people who don't do "This thing I'm an expert at and claim is not so hard" as often as the expert in question it really is that hard. Things get easier, and people better, with practice. Now, if this is something you plan on using a lot in your job / particular programming field then you shouldn't be afraid of multi-threaded programming but if this is going to be a small passing item that you work with rarely if ever you should probably use existing libraries / abstractions for this type of thing.




Has the author really written lots of multithreaded code?

Lots of people think they understand multithreading because they understand the synchronization primitives. "I'll just share this synchronized HashMap among my threads and everything will be fine". Not so. Because your code makes implicit assumptions about that HashMap all the time, e.g. that you can check if an element is in the map and if not, add it (but another thread added it after you checked); that the map won't change and throw an exception while you iterate over it because my loop doesn't change it, etc.

I don't think granularity is the hardest thing about multithreaded programming, it's these implicit assumptions. In an imperative language we just tend to think about our code as if it is single threaded and nothing changes until you change it. Then you get rare and irreproducible bugs in your program.


I think I agree with both. The impression I got from the article was that even after you've carefully identified all shared datastructures, and made sure they are as few as possible and locked properly, you still have to decide how to structure the parallelization. This will have effects on how it scales to higher # of cores and larger problems and is, in some sense, a less constrained problem because you don't know where to look. At least wrt synchronization, you can make a list of shared data and go through it.


The article says: "You can almost always use a simple locked data-structure for synchronization fairly painlessly (and with a bit of practice, you can usually write one fairly painlessly, too)."

If we focus on the first part, in my experience it is wrong: you can't rely on the data structure to do synchronization for you, because these structures only guarantee that internally they will work consistently, not that using them you can forget about synchronization and threading. Quite often you need to do your own synchronization on top of them, and it is easy to miss some cases. That's what my examples are about.


Lots of people think they understand multithreading because they understand the synchronization primitives.

Well yeah. But the primitives aren't "synchronized hash maps", they're "transactions".


I think this is where a pure functional language like Haskell really shines.

Haskell might be a turn off to some people because it doesn't allow the quick and dirty solution for people who know what they're doing, and I'm sure there are those who have been permanently turned off to "protecting the programmer from himself" by such limp-wristed languages as Java, but you've got to admit there's merit to a language where instead of spending 5 years going through the school of hard knocks with production bugs, the programmer is baffled from the get-go and has to go ask an expert right away, resulting in much more solid code from the first version.


And you can do the dirty tricks, if you really want to, in Haskell. The code will just make this obvious to anyone watching (lots of unsafePerformIO).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: