Blog Post

Rick Molloy: Actor-based Programming in C++ - Control Flow versus Data Flow

Download this episode

Download Video

Description

Rick Molloy is back and he's got some code and coding techniques to share. Thank you Rick! This tutorial/example is done in C++, but the concepts span languages (actor-based, data flow style of programming)

Here, Rick explores converting a simple loop to a set of actors or agents that communicate via message passing.  In particular he looks at the difference between a "control flow" style implementation and a "data flow" style implementation. The actor based approach is great because it separates the guts of the work from the loop logic so code looks more like the flow charts we draw on our whiteboards.

But, there's some down sides with the control flow approach and implementing the data flow approach can be tricky.  So Rick wanted to walk through an example of both to help illustrate the differences.

The downside to the control flow approach comes in when you have lots of agents, there tends to be either a 1:1 coupling of threads to tasks OR the tasks start taking on more than one responsibility and become less manageable.

A data flow style approach helps with this, because it decouples the 1:1 thread to task relationship but it can be an awkward refactoring if you're not used to it, it takes more code, and there aren't many examples available to look at on the web so Rick wanted to share another one.

 Download the code for this demo (will work in VC++ 2010)

Embed

Format

Available formats for this video:

Actual format may change based on video formats available and browser capability.

    The Discussion

    • User profile image
      ryanb

      The code download link is not working, and is in fact redirecting to a malware site.  Please fix.

       

    • User profile image
      Charles

      Fixed. Sorry about that!

    • User profile image
      Ryan Riley

      Thanks for fixing that, Charles.

    • User profile image
      ryanb

      Yes, much better now.  Thanks.

    • User profile image
      Benjamin Lindley

      Normally, I avoid macros like the plague. But that DEFINE_HAS_MEMBER is just too brilliant.

    • User profile image
      rickmolloy

      @Benjamin - multiple folks contributed to the concise DEFINE_HAS_MEMBER in the example, my original version was more verbose.

      In general I also try to avoid macros but I think there are a few really good use cases for them.  For me they involve things like converting class / variable names to strings (we see this a lot in debugging / tracing) or in cases where you want the name of something in a class (in a macro) to vary but not the structure.

      In C++11 I think template aliases will help with some places where folks are using macros now as will being able to allow constructors to call other constructors, but I don't think it will help in this instance because the preprocessor is converting the type to a string.

      The original DEFINE_HAS_MEMBER is part of the concrt sample pack in connect.h at http://code.msdn.com/concrtextrasAnd">http://code.msdn.com/concrtextras

      And Xiang Fan has a blog post on how to do this without decltype at:
      http://blogs.msdn.com/b/xiangfan/archive/2009/02/09/c-template-trick-detecting-the-existence-of-class-member-at-compile-time.aspx-Rick">http://blogs.msdn.com/b/xiangfan/archive/2009/02/09/c-template-trick-detecting-the-existence-of-class-member-at-compile-time.aspx

      -Rick

       

    • User profile image
      Glen

      Hi Rick

      Subtle. I initially wondered what the value/purpose was of such an at length discussion of what appears to a simple and unremarkable style of code. Especially if the transformed code might actually run slower on some machines.

      After more consideration though I am realising both that this style of code is quite profound such that it could eventually become quite the norm; and that your long focus on a simple example to demonstrate the core concepts being introduced was a good idea. So thanks, it hit the mark for me.

    • User profile image
      rab36

      Hi Rick,

      thanks a lot for this lecture on dataflow patterns. For me it was very interesting to see, that the equation 1 agent = 1 thread does not necessarly hold when using call, transform, etc. to implement the agent. This is good news, because that was one of my main concerns when thinking about using the asynchronous agents library.

      Bernd

       

    • User profile image
      rickmolloy

      @Glen. Thank you I'm glad this was useful.

      @Bernd.  Just confirming in concrt, the scheduler / resource manager control the number of threads. If you have 1000 calls and send 1000 messages to them there will be approximately 4 threads running at once on a 4-core processing those thousand messages until they are completed. You will in fact see more threads, but they are not usually usuall actively processing items, they're kept in reserve in case an API call is made that is considered 'blocking'. 

      'Agents' can hold onto a thread when they don't exit their run method in a short amount of time (as do all tasks), but there only a  few examples online showing folks how to do this.  In reality you may want to have a mix of 'control flow' and 'dataflow' agents in an application, it just depends on what you need.

    • User profile image
      AlessandroV

      Hi Rick,

      the lecture is very interesting and I tried to modify the sample code to the two kinds of agents but most of the time it doesn't work (it locks, or crashes with "pure virtual function call").

      What am I missing?

    • User profile image
      rickmolloy

      @AlessandroV - what are you trying to change?  There are several more samples on msdn here: http://msdn.microsoft.com/en-us/library/dd492627.aspx

    Comments closed

    Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.