[Haskell-cafe] Can you do everything without shared-memory concurrency?

Maarten Hazewinkel maarten.hazewinkel at gmail.com
Wed Sep 10 05:55:04 EDT 2008


Hi Bruce,

Some comments from an 11 year Java professional and occasional Haskell  
hobbyist.


On 9 Sep 2008, at 20:30, Bruce Eckel wrote:

> So this is the kind of problem I keep running into. There will seem  
> to be consensus that you can do everything with isolated processes  
> message passing (and note here that I include Actors in this  
> scenario even if their mechanism is more complex). And then someone  
> will pipe up and say "well, of course, you have to have threads" and  
> the argument is usually "for efficiency."

One important distinction to make, which can make a lot of difference  
in performance, is that shared memory itself is not a problem. It's  
when multiple threads/processes can update a single shared area that  
you get into trouble. A single updating thread is OK as long as other  
threads don't depend on instant propagation of the update or on an  
update being visible to all other threads at the exact same time.


> I make two observations here which I'd like comments on:
>
> 1) What good is more efficiency if the majority of programmers can  
> never get it right? My position: if a programmer has to explicitly  
> synchronize anywhere in the program, they'll get it wrong. This of  
> course is a point of contention; I've met a number of people who say  
> "well, I know you don't believe it, but *I* can write successful  
> threaded programs." I used to think that, too. But now I think it's  
> just a learning phase, and you aren't a reliable thread programmer  
> until you say "it's impossible to get right" (yes, a conundrum).

In general I agree. I'm (in all modesty) the best multi-thread  
programmer I've ever met, and even if you were to get it right, the  
next requirements change tends to hit your house of cards with a large  
bucket of water.
And never mind trying to explain the design to other developers. I  
currently maintain a critical multi-threaded component (inherited from  
another developer who left), and my comment on the design is "I cannot  
even properly explain it to myself, let alone someone else". Which is  
why I have a new design based on java.util.concurrent queues on the  
table.

> 2) What if you have lots of processors? Does that change the picture  
> any? That is, if you use isolated processes with message passing and  
> you have as many processors as you want, do you still think you need  
> shared-memory threading?

In such a setup I think you usually don't have directly shared memory  
at the hardware level, so the processors themselves have to use  
message passing to access shared data structures. Which IMHO means  
that you might as well design your software that way too.


> A comment on the issue of serialization -- note that any time you  
> need to protect shared memory, you use some form of serialization.  
> Even optimistic methods guarantee serialization, even if it happens  
> after the memory is corrupted, by backing up to the uncorrupted  
> state. The effect is the same; only one thread can access the shared  
> state at a time.

And a further note on sharing memory via a transactional resource (be  
it STM, a database or a single controlling thread).
This situation always introduces the possibility that your update  
fails, and a lot of client code is not designed to deal with that. The  
most common pattern I see in database access code is to log the  
exception and continue as if nothing happened. The proper error  
handling only gets added in after a major screwup in production  
happens, and the usually only the the particular part of the code  
where it went wrong this time.


Kind regards,

Maarten Hazewinkel


More information about the Haskell-Cafe mailing list