    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: A C++ Petri Net Framework For Multithreaded
Programming</title>
        <link>http://accu.org/index.php/journals/357</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #54 - Apr 2003 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="http://accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="http://accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="http://accu.org/index.php/journals/c78/">Overload</a>

                     &gt;                         <a href="http://accu.org/index.php/journals/c157/">54</a>
                    (10)
<br />

                                            <a href="http://accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="http://accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="http://accu.org/index.php/journals/c65/">Programming</a>
                    (488)
<br />

                                            <a href="http://accu.org/index.php/journals/c157-65/">Any of these categories</a>

                    -                        <a href="http://accu.org/index.php/journals/c157+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;A C++ Petri Net Framework For Multithreaded
Programming</h1>
<p><strong>Author:</strong>&nbsp;Administrator</p>
<p>
<strong>Date:</strong> 02 April 2003 22:57:18 +01:00 or Wed, 02 April 2003 22:57:18 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>One of the pitfalls of multithreaded programming is deadlock, a
situation where each thread exclusively holds one resource while
waiting for another's resource. Every non-trivial multithreaded
program must contend with deadlocks. One strategy is to detect a
deadlock at runtime and take some action to remove it (e.g. send a
quit signal to one of the threads). Another approach is to design
the program carefully to avoid deadlocks. In practice, this can be
a difficult task. The Petri net framework presented in this article
supports a hybrid approach, combining careful design with runtime
checks to create a deadlock-free process.</p>
<p>Like UML activity diagrams, Petri nets are graphical
representations of processes providing a state-oriented view and an
activity-oriented view. In other words, Petri nets simultaneously
represent the state of a system and what the system is doing. What
makes Petri nets powerful is their semantics; formal mathematical
analysis techniques can be used to determine characteristics of a
given net. For example, it can be proven that a particular net with
the right initial conditions will not reach a deadlocked state.</p>
<p>This article briefly discusses the properties of Petri nets and
presents a demonstration of a (intentionally) poorly designed
application using a C++ framework with Win32 synchronization
objects. The framework supports rapid implementation of a process
that has been described with a Petri net and is capable of runtime
or post-build testing for deadlocks.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e28" id="d0e28"></a>Petri Nets</h2>
</div>
<p><img src="/var/uploads/journals/resources/printer%20application%20petri%20net.png"
align="right">The Petri Net is named after C.A. Petri, who
developed the concept as part of his doctoral thesis in 1962. In
mathematical terms, a Petri net is a directed bipartite graph. The
two types of vertices are called places and transitions. The
directed edges, known as arcs, connect places to transitions, and
transitions to places.</p>
<p>A place is a container that holds zero or more tokens. The set
of places and the number of tokens in each represents the state of
the system. This set is called a marking. A transition represents
an activity of the system. The arcs that point towards a transition
are input arcs, and those that point towards a place are output
arcs. Each arc has an associated arc expression, which indicates
how many tokens will be added to or removed from a place when the
transition executes. The arc expression is usually 1, in which case
it is omitted from drawings.</p>
<p>A transition is considered enabled when enough tokens exist in
the places connected to its input arcs for all input arc
expressions to be satisfied. Only enabled transitions can execute.
After an enabled transition has completed, tokens are added to the
places connected to its output arcs according to the output arc
expressions. The net now has a new marking, and a new set of
enabled transitions exists. A dead marking, or deadlocked state, is
one where the set of enabled transitions is empty.</p>
<p>Figure 1 is a Petri net representation of a theoretical, and
flawed, file printing application with its initial marking
displayed. The application has a hold-and-wait problem and will
deadlock. Places P0, P3, P6, and P7 contain one token each. The
tokens at P0 and P3 represent the number of threads which can
execute in the left chain of execution and the right chain,
respectively. The tokens at P6 and P7 represent a lock on a file or
printer resource, respectively. A single token in each resource
indicates that the locks are exclusive.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e40" id="d0e40"></a>Concurrency and
Conflict</h2>
</div>
<p>The initial marking <tt class="literal">M0</tt> of the example
Petri net can also be described as the set of enabled transitions;
<tt class="literal">M0 = { T0, T3 }</tt>. If <tt class=
"literal">T0</tt> fires first, <tt class="literal">T3</tt> is still
enabled, and vice versa. <tt class="literal">T0</tt> and <tt class=
"literal">T3</tt> are enabled concurrently. By systematically
tracing execution of the Petri net and the evolution of its
markings we build what is called the occurrence graph, the graph of
all markings reachable from the initial marking. Firing <tt class=
"literal">T0</tt> gives <tt class="literal">M1 = { T1, T3 }</tt>.
If <tt class="literal">T1</tt> fires first, <tt class=
"literal">T3</tt> is disabled, and vice versa. This situation is
called a conflict. <tt class="literal">T1</tt> and <tt class=
"literal">T3</tt> are enabled, but not concurrently.</p>
<p>The most efficient multithreaded applications would maximize
concurrent states and minimize conflicted states, and Petri net
analysis can help in their design.</p>
<p>Continuing our systematic execution, <tt class="literal">T1</tt>
gives <tt class="literal">M2 = { T2 }</tt>, and <tt class=
"literal">T2</tt> gives <tt class="literal">M0</tt> again. No
problems yet. Let's return to <tt class="literal">M1</tt>, but this
time <tt class="literal">T3</tt> fires first, giving <tt class=
"literal">M3 = { }</tt>. Deadlock. If through some intervention we
were to give <tt class="literal">T0</tt> and <tt class=
"literal">T1</tt> priority over <tt class="literal">T3</tt>, we
will have created a live-lock situation. The chain on the right
(<tt class="literal">T3</tt>, <tt class="literal">T4</tt>,
<tt class="literal">T5</tt>) would never execute.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e124" id="d0e124"></a>The
Framework</h2>
</div>
<p>The Petri net framework is anchored by the <tt class=
"classname">CPetriNet</tt> class, which aggregates <tt class=
"classname">Place</tt>, <tt class="classname">Transition</tt>,
<tt class="classname">Arc</tt>, and <tt class=
"classname">Thread</tt>. Listing 1 shows how a net is constructed
and operated in a console application <tt class=
"function">main()</tt> function. Both <tt class=
"classname">Place</tt> and <tt class="classname">Transition</tt>
inherit from <tt class="classname">Node</tt>, which keeps track of
arc connections. For details on these classes see the full source
archive.</p>
<div class="sidebar">
<pre class="programlisting">
int _tmain(int argc, _TCHAR* argv[]) {
  CPetriNet net;

  // places 0-5 are generic
  for(int k = 0; k &lt; 6; ++k) {
    net.AddPlace(new CPlace);
  }

  // places 6, 7 are specific
  net.AddPlace(new CPlaceFile);
  net.AddPlace(new CPlacePrinter);

  // transitions 0-5
  net.AddTransition(new CTransitionGetFile);
  net.AddTransition(
  new CTransitionGetPrinter);
  net.AddTransition(new CTransitionPrint);
  net.AddTransition(
  new CTransitionGetPrinter);
  net.AddTransition(new CTransitionGetFile);
  net.AddTransition(new CTransitionPrint);

  // string describing all arc connections
  string strArcs =
      &quot;p0t0t0p1p1t1t1p2p2t2t2p0p3t3t3p4p4t4&quot; \
      &quot;t4p5p5t5t5p3p6t0p6t4t2p6t5p6p7t1p7t3&quot; \
      &quot;t2p7t5p7;&quot;;
  net.MakeConnections(strArcs);

  // set initial marking
  net.GetPlace(0)-&gt;AddTokens(1);
  net.GetPlace(3)-&gt;AddTokens(1);
  net.GetPlace(6)-&gt;AddTokens(1);
  net.GetPlace(7)-&gt;AddTokens(1);

  // create two threads
  net.AddThread(new CThread);
  net.AddThread(new CThread);
  if(!net.Test()) {
    cout &lt;&lt; &quot;ERROR: deadlock state exists&quot;
         &lt;&lt; endl;
    return 1;
  }
  net.Start();

  // run demonstration for 30 seconds
  Sleep(30000);
  net.Stop();
  return 0;
}
</pre>
<p><span class="bold"><b>Listing 1</b></span></p>
</div>
<p>Places 0-5 in the example are generic Petri net places, which
provide valuable state information but do not represent resources.
Resource classes inherit from Place and implement an additional
interface to the resource.</p>
<p><tt class="classname">Transition</tt> is an abstract class.
Users implement the <tt class="methodname">Execute()</tt> method in
subclasses. Each transition is executed by the next available
thread. It's important not to think of the execution chains in
Figure 1 as cycles for a single thread. Resource interfaces in
classes inheriting from Place must not use per-thread
synchronization or locking mechanisms. A properly constructed net
provides the necessary locking.</p>
<p><tt class="methodname">Execute()</tt> methods use the Visitor
pattern (Gamma et al., 1995) to access Place resources. Classes
derived from Place define an <tt class="methodname">Accept()</tt>
method for each client class derived from Transition. <tt class=
"methodname">Execute()</tt> methods call <tt class=
"methodname">Accept()</tt> on each connected place in some defined
order, as shown below.</p>
<pre class="programlisting">
void DerivedTransition::Execute() {
  arcInput_[1]-&gt;
          GetPlace()-&gt;Accept(*this);
  // visit other places. . .
}
</pre>
<p>One consequence of Visitor is that the base class <tt class=
"classname">Place</tt> must declare <tt class=
"methodname">Accept()</tt> methods for all derived <tt class=
"classname">Transition</tt> types. To preserve the framework-like
design of <tt class="classname">Place</tt>, a <tt class=
"classname">PlaceNodeVisitor</tt> interface class defines empty
<tt class="methodname">Accept()</tt> methods. The <tt class=
"classname">Place</tt> class uses multiple inheritance to expose a
modifiable <tt class="classname">PlaceNodeVisitor</tt> interface
without requiring changes to <tt class="classname">Place</tt>'s
definition.</p>
<p>Another consequence of Visitor is that <tt class=
"classname">Transition</tt> classes become stateful, essentially
duplicating data from a <tt class="classname">Place</tt> to be used
by <tt class="methodname">Accept()</tt> calls to subsequent
<tt class="classname">Place</tt>s. An alternative design might use
runtime type information (RTTI) to access connected derived
<tt class="classname">Place</tt>s with <tt class=
"literal">dynamic_cast</tt>:</p>
<pre class="programlisting">
void DerivedTransition::Execute() {
  DerivedPlace* p =
    dynamic_cast&lt;DerivedPlace*&gt;(
      arcInput_[1]-&gt;GetPlace() );
  assert(p != 0);
  // use DerivedPlace's methods. . .
}
</pre>
<p>The RTTI design does away with <tt class=
"classname">PlaceNodeVisitor</tt> and allows purely behavioural
derived <tt class="classname">Transition</tt> classes to use
multiple derived <tt class="classname">Place</tt>s within a single
function body.</p>
<p>Both designs tie the identity of a specific resource to the
order in which it is connected by the <tt class=
"methodname">MakeConnections()</tt> function, determined by the
ordering of the string describing the list of connections. In the
RTTI design, asserting that the cast pointer is not null is a good
debug check.</p>
<p>The largest number of concurrently enabled transitions in any
marking in the occurrence graph determines the maximum number of
threads that can process the net. Presently this would be set
during design, but a function could feasibly be written to create
the appropriate number of threads at runtime.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e255" id="d0e255"></a>Net
Processing</h2>
</div>
<p><img src="/var/uploads/journals/resources/thread%20state%20chart.png" align=
"right">Figure 2 is a state chart of <tt class=
"classname">Thread</tt> processing of the net. Processing is
started by a call to <tt class="methodname">PetriNet::Start()</tt>.
This calculates the set of enabled transitions from the initial
token placement and creates a Win32 semaphore with an initial count
of 1 and a maximum count equal to the number of threads. A Win32
semaphore is a synchronization object that decrements its count for
each thread it allows to pass and blocks threads while its count is
zero. When the thread releases the semaphore its count is
incremented.</p>
<p>Operations that change the internal state of a Petri net (e.g.
adding or removing tokens) must be performed atomically. <tt class=
"classname">PetriNet</tt> contains a Win32 mutex for this purpose.
A mutex allows a single thread to pass and blocks all other threads
until it is released. Mutex is short for mutual exclusion. A thread
can gain exclusive access to the net by creating a <tt class=
"classname">ScopedLock</tt> object. <tt class=
"classname">ScopedLock</tt>'s constructor accepts a <tt class=
"classname">PetriNet</tt> reference and is a <tt class=
"literal">friend</tt> class to <tt class="classname">PetriNet</tt>,
so it can acquire a lock on <tt class="classname">PetriNet</tt>'s
mutex. When the created lock object goes out of scope its
destructor releases <tt class="classname">PetriNet</tt>'s
mutex.</p>
<p>A new marking is calculated twice per loop, the first time after
removing tokens from input places. This marking may be empty due to
a conflict or because only one transition was enabled in the
previous marking, but this does not produce deadlock. If the new
marking calculated after removing tokens still has enabled
transitions, the semaphore is released, enabling any waiting thread
to process a remaining transition concurrently.</p>
<p>After executing the transition and adding tokens to output
places, a new marking is calculated again. To prevent a live-lock,
the order of the calculated marking is shuffled randomly so that
the same transition in a conflicted pair is not picked first every
time. If the marking is empty the semaphore is not released and the
system is deadlocked.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e297" id="d0e297"></a>Post-build
Deadlock Testing</h2>
</div>
<p>The <tt class="methodname">PetriNet::Test()</tt> method builds
the occurrence graph by calculating every marking reachable from
the initial marking (without the random shuffle). Intermediate
(post remove, pre add) markings are not considered here. If an
empty marking is found the test fails and the function returns
false. The test algorithm in pseudo-code looks like this:</p>
<pre class="programlisting">
Calculate set of enabled transitions from 
                 initial token placement.
If set is empty declare failure.
  Name the initial set, count it as
                 unvisited and add it to a list.
Call the initial set the current set.
While there are unvisited sets:
  Take the first unvisited transition in
                 the current set.
  Push the transition and the name of the
                 current set onto a stack.
  Remove tokens from the places connected
                 to the transition's inputs.
  Add tokens to the places connected to
                 the transition's outputs.
  Mark this transition in this set
                 visited.
  Calculate the new set.
  If set is empty declare failure.
  Else if set not in list:
    Name new set.
    Add it to the list.
    Mark it unvisited.
    Make it the current set.
  End
  If all transitions in the current set
                 have been visited:
    Declare the set visited.
    Undo the transition token move at the
                 top of the stack.
    Make the set at the top of the stack
                 the current set.
  End
End
</pre>
<p>In the example application <tt class="function">Test()</tt> is
called prior to <tt class="function">Start()</tt> to prevent a
deadlocked net from running. <tt class="function">Test()</tt> works
without executing any of the net's transitions. A practical
application could be executed with a command line switch that
causes <tt class="function">main()</tt> to call <tt class=
"function">Test()</tt> and return an exit code. This could be
performed as a post-build step in development. This feature would
be helpful if the structure of the net or the number of resources
were undergoing design.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e324" id="d0e324"></a>Fixing the
Demo Application</h2>
</div>
<p>Suppose instead of a printer resource we constructed a print
queue resource that took file submissions in an atomic operation.
With this change to the resource we would obtain not an exclusive
lock on a printer but a lock on a queue location. Adding a second
token to the printer resource in the initial marking and building
the occurrence graph proves that a two-position printer queue would
prevent deadlock. The markings are as follows:</p>
<pre class="programlisting">
M0 = { T0, T3 }
M1 = { T1, T3 }
M2 = { T2, T3 }
M3 = { T2 }
M4 = { T0, T4 } (conflict)
M5 = { T1 }
M6 = { T5 }
</pre>
<p>Figure 3 shows the output of the demo application with two
initial printer tokens. The results of each marking calculation are
printed as well, with the token placement following the set of
enabled transitions.</p>
<div class="sidebar">
<pre class="screen">
start
{ 0 3 } [ 1 0 0 1 0 0 1 2 ]
{ 0 } [ 1 0 0 0 0 0 1 1 ]
thread 3548 gets printer
{ } [ 0 0 0 0 0 0 0 1 ]
{ } [ 0 0 0 0 1 0 0 1 ]
thread 3648 gets file
{ 1 } [ 0 1 0 0 1 0 0 1 ]
{ } [ 0 0 0 0 1 0 0 0 ]
thread 3548 gets printer
{ 2 } [ 0 0 1 0 1 0 0 0 ]
{ } [ 0 0 0 0 1 0 0 0 ]
thread 3648 PRINTING: Hello World!
{ 0 4 } [ 1 0 0 0 1 0 1 1 ]
{ } [ 1 0 0 0 0 0 0 1 ]
thread 3548 gets file
{ 5 } [ 1 0 0 0 0 1 0 1 ]
{ } [ 1 0 0 0 0 0 0 1 ]
thread 3648 PRINTING: Hello World!
{ 3 0 } [ 1 0 0 1 0 0 1 2 ]
{ 3 } [ 0 0 0 1 0 0 0 2 ]
thread 3548 gets file
{ } [ 0 0 0 0 0 0 0 1 ]
thread 3648 gets printer
{ 1 } [ 0 1 0 0 0 0 0 1 ]
{ 1 } [ 0 1 0 0 1 0 0 1 ]
{ } [ 0 0 0 0 1 0 0 0 ]
thread 3548 gets printer
{ 2 } [ 0 0 1 0 1 0 0 0 ]
{ } [ 0 0 0 0 1 0 0 0 ]
thread 3648 PRINTING: Hello World!
{ 4 0 } [ 1 0 0 0 1 0 1 1 ]
{ } [ 0 0 0 0 1 0 0 1 ]
thread 3548 gets file
{ 1 } [ 0 1 0 0 1 0 0 1 ]
{ } [ 0 0 0 0 1 0 0 0 ]
thread 3648 gets printer
{ 2 } [ 0 0 1 0 1 0 0 0 ]
{ } [ 0 0 0 0 1 0 0 0 ]
thread 3548 PRINTING: Hello World!
{ 0 4 } [ 1 0 0 0 1 0 1 1 ]
{ } [ 1 0 0 0 0 0 0 1 ]
thread 3648 gets file
{ 5 } [ 1 0 0 0 0 1 0 1 ]
{ } [ 1 0 0 0 0 0 0 1 ]
thread 3548 PRINTING: Hello World!
{ 3 0 } [ 1 0 0 1 0 0 1 2 ]
. . .continues. . .
</pre>
<p><span class="bold"><b>Figure 3</b></span></p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e339" id="d0e339"></a>Future
Work</h2>
</div>
<p>There is a lot of room for future improvement of the framework.
A feature of Petri nets not implemented yet is the inhibitor arc,
in which the presence of tokens in the connected place inhibits the
connected transition. Concepts from higherlevel Petri nets would
add powerful functionality. For example, colored Petri nets allow
tokens to have a type (or color) property. This enables the use of
complex arc expressions involving type and quantity and makes
possible decision branches as part of the net structure.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e344" id=
"d0e344"></a>Conclusion</h2>
</div>
<p>A multithreaded process designed using Petri net analysis might
be deployed rapidly enough using this framework to justify the
added runtime costs. For more information on Petri nets two
references are listed below [<a href=
"#Marsan-et-al">Marsan-et-al</a>, <a href=
"#Jensen">Jensen</a>].</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e355" id="d0e355"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Marsan-et-al" id=
"Marsan-et-al"></a>
<p class="bibliomixed">[Marsan-et-al] Marsan, M. Ajmone et al.
1995. <span class="citetitle"><i class="citetitle">Modelling with
Generalized Stochastic Petri Nets</i></span>. Chichester: John
Wiley &amp; Sons.</p>
</div>
<div class="bibliomixed"><a name="Jensen" id="Jensen"></a>
<p class="bibliomixed">[Jensen] Jensen, Kurt. 1996. <span class=
"citetitle"><i class="citetitle">Colored Petri Nets, vol.
1</i></span>. 2nd ed. Berlin: Springer-Verlag.</p>
</div>
<div class="bibliomixed"><a name="Gamma-et-al" id=
"Gamma-et-al"></a>
<p class="bibliomixed">[Gamma-et-al] Gamma, Erich et al. 1995.
<span class="citetitle"><i class="citetitle">Design
Patterns</i></span>. Reading: Addison-Wesley.</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
