The future of concurrent programming

Regan Heath regan at netmail.co.nz
Tue May 29 10:38:49 PDT 2007


Daniel Keep Wrote:
> freeagle wrote:
> > Why do people think there is a need for another language/paradigm to
> > solve concurrent problem? OSes deal with parallelism for decades,
> > without special purpose languages. Just plain C, C++. Just check Task
> > manager in windows and you'll notice there's about 100+ threads running.
> > If microsoft can manage it with current languages, why we cant?
> > 
> > freeagle
> 
> We can; it's just hard as hell and thoroughly unenjoyable.  Like I said
> before: I can and have written multithreaded code, but it's so utterly
> painful that I avoid it wherever possible.

I must be strange then because after 5+ years of multithreaded programming it's the sort I prefer to do.  Each to their own I guess.

I think perhaps it's something that can be learnt, but it takes a bit of time, similar in fact to learning to program in the first place.  I enjoy the challenge of it and I think once you understand the fundamental problems/rules/practices with multithreaded development it becomes almost easy, almost.

> It's like trying to wash a car with a toothbrush and one of those giant
> novelty foam hands.  Yeah, you could do it, but wouldn't it be really
> nice if someone would go and invent the sponge and wash-cloth?

I think with some higher level constructs it becomes easier.  For example one of the main problems you face are deadlocks.  A common cause of a deadlocks is:

class A {
  void foo() {
    synchronize(this) { ... }
  }
}

void main()
{
  A a = new A();
  synchronize(a) {
    a.foo();
  }
}

now, I haven't tested the above in D but in Java and C# the 'lock' statement causes a deadlock above because you cannot lock the same object twice, even from the same thread.

In my previous job we used a mutex object that allowed the same thread to lock the same object any number of times, counting the number of lock calls and requiring an equal number of unlock calls.  This idea makes life a lot easier.  No more deadlocks of this type.

That just leaves the deadlock you get when you say:

synchronize(a) { synchronize(b) { .. } }

and in another thread:

synchronize(b) { synchronize(a) { .. } }

Given the right (or rather wrong) timing this can result in a dealock of both threads.  This situation is less common simply because it's less common for 2 blocks of code in 2 different threads to need 2 or more mutexes _at the same time_.  Or, at least, that is my experience.

In my previous job we went so far as to intentionally terminate the process if a deadlock was detected and could then give the exact file:line of the last lock request making it fairly trivial to debug.  We could do this because our server process had a 2nd process watching over it, and restarting it at a moments notice.

It's things like these which make multithreaded programming much easier for developers to get their head around.

I wonder what D's synchronized statement does?  Does it allow multiple locks from the same thread?  It should, especially given that it is impossible to forget the unlock call (that in itself is a great boon to multithreaded development).

Another good idea is to provide a ThreadPool construct, do we have one of those floating around (pun intended).  The idea being that when you need a thread you ask the pool for one and it supplies it, then once you're done with it you release it back into the pool for the next piece of code to pick it up and run with it (get it, run with it, like a ball... well I thought it was funny).

Just a few ideas.  Like several people have posted, the next great idea is probably waiting to be thought up!  but, in the meantime we can make life a little easier, one step at a time.

Regan Heath



More information about the Digitalmars-d mailing list