Concurrency, was Re: Doh! Stupid Programming Mistakes <humor>

Bryan Sant bryan.sant at gmail.com
Thu Oct 26 14:19:18 MDT 2006


On 10/26/06, Shane Hathaway <shane at hathawaymix.org> wrote:
> Threads provide no way to enforce a communication protocol.  You can't

That's because you don't need a communication protocol.  Your
accessing memory directly and the "protocol" is the natural semantics
or your programing language.  When I want to read a value, I call a
method to read.  When I want to write a value, I call a method to
write.

> write an interface specification that states all of the ways a parent
> thread will talk to a child thread, since threads make it too easy to

You mean like an interface in Java.

> manipulate inter-thread state out of band.  Even if you choose rules for

Nope.  Because I don't have global data.  How do you manipulate
non-global data?  You must have a reference to it...  And guess who
controls what references get passed to my new thread?

--- MyThread.java ---
public class MyThead extends Thread {
  public void run() {
    while (true)
      System.out.println("I can't access a dang thing because it's all
out of scope :-(");
  }
}

--- End of MyThread.java ---

--- Test.java ---
public class Test {

  public String dataIDontWantAnyThreadToTouch = "Shane is misinformed";

  public static void main(String[] args) {
    Thread myThread = new MyThread();
    myThread.start();
  }

}
--- End of Test.java ---

Okay, now I want you to extend MyThread, or create your own thread
that will access the field in Test and change it to "Shane rules!".

> inter-thread communication and stick to them, future maintainers of your
> code might accidentally violate those rules, receiving no warning for
> doing so.  Your own refactoring could break your rules.  Breaking the
> rules can lead to intermittent bugs such as race conditions and
> deadlocks.  These bugs are the kind that only show up under heavy load,
> and thus cost a lot of money to fix.

Uggh.  No, future maintainers will not manipulate inter-thread state
out of band, because they don't have scope access.  My OO software
doesn't have global data, so how exactly will current or future
spawned threads access my heap data?  The only way this could happen
is if a new developer creates a new thread and passes references to
data he shouldn't into his thread (via constructor or setter methods)
from the controlling thread.  But consider that this same "flaw"
exists in your approach where a new developer could expose shared data
via your protocol that you never intended for him to expose.

> Using child processes forces you to define a communication protocol and
> strongly encourages future maintainers to modify that protocol rather

You mean modify that protocol incorrectly and introduce new bugs,
inconsistencies, data corruption and a host of other problems.  This
protocol approach offers nothing that couldn't be done in-process.  It
just makes more artificial work (lines of code) required to expose and
marshal new shared data.

> than manipulate state out of band.  This mostly eliminates a whole class
> of race conditions.  It does not eliminate deadlocks, but you can fix
> deadlocks by analyzing the interprocess communication.

And it dumps your performance through the floor because your doing
full out of process memory copies often time with heavy-weight IPC
protocols with overhead on top of that making your means of
communication hundreds of times slower than isolated and protected
direct heap access.  Depending on your app, that may be acceptable
because your not moving data across your IPC link often.  However, if
you have anything other than a meager interaction level, you'll be
paying a significant CPU and I/O cost for doing things out-of-process.
 Way to go.

> I've personally broken someone else's inter-thread communication pattern
> without knowing it, and the breakage led to a month of diagnostic effort
> on a production system by 4-5 developers.  It turned into a serious risk
> to the business.  Today I prefer concurrency models that enforce a
> communication protocol, unlike threads.

Your argument for a protocol is retarded.  The protocol is only going
to manage the marshaling of bytes back and forth between two or more
processes.  At both ends of this pipe (which is managed by your
fantabulous protocol) you still have to deal with shared data issues.
You have most of the same problems that you would have with threads,
except that your performance sucks in comparison and your debugging is
scattered to many processes.

There are reasons for using out-of-process communication but not the
reasons you're stating.  Your approach solves nothing compared to Java
threading.  It is much slower, you have more code to maintain, and
it's more error prone.  Nice design.

-Bryan



More information about the PLUG mailing list