[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