<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Igor Ostrovsky Blogging &#187; Concurrency</title>
	<atom:link href="http://igoro.com/archive/category/concurrency/feed/" rel="self" type="application/rss+xml" />
	<link>http://igoro.com</link>
	<description>On programming, technology, and random things of interest</description>
	<lastBuildDate>Fri, 23 Jul 2010 05:24:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Video of my PLINQ session at PDC 2009</title>
		<link>http://igoro.com/archive/video-of-my-plinq-session-at-pdc-2009/</link>
		<comments>http://igoro.com/archive/video-of-my-plinq-session-at-pdc-2009/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 05:25:21 +0000</pubDate>
		<dc:creator>Igor Ostrovsky</dc:creator>
				<category><![CDATA[Concurrency]]></category>

		<guid isPermaLink="false">http://igoro.com/?p=353</guid>
		<description><![CDATA[PDC 2009 was an exciting event, with announcements about Azure, Silverlight 4, and Office 2010 popping up one after another. For me, there was another reason why this year&#8217;s PDC was exciting &#8211; it was my first chance to present in a major conference. The video of my session is available as Silverlight video, and [...]]]></description>
			<content:encoded><![CDATA[<p>PDC 2009 was an exciting event, with announcements about Azure, Silverlight 4, and Office 2010 popping up one after another. For me, there was another reason why this year&#8217;s PDC was exciting &#8211; it was my first chance to present in a major conference.</p>
<p><a href="http://microsoftpdc.com/Sessions/FT21"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://igoro.com/wordpress/wp-content/uploads/2009/11/image.png" width="648" height="370" /></a> </p>
<p> <span id="more-353"></span>
<p>The video of my session is available as <a href="http://microsoftpdc.com/Sessions/FT21">Silverlight video</a>, and also as <a href="http://ecn.channel9.msdn.com/o9/pdc09/wmvhigh/FT21.wmv">high-quality WMV</a> and <a href="http://ecn.channel9.msdn.com/o9/pdc09/wmv/FT21.wmv">standard-quality WMV</a>. Here are the <a href="http://ecn.channel9.msdn.com/o9/pdc09/ppt/FT21.pptx">slides</a>. Check it out and let me know how I did!</p>
<p>And, here are videos of all <a href="http://blogs.msdn.com/pfxteam/archive/2009/11/21/9926691.aspx">PDC sessions related to parallel programming</a>.</p>
<p>Never having presented at PDC before, I didn’t know how many people to expect at my session. I was happy with the turn out – this is a view of my session from the back of the room:</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="SNC00100" border="0" alt="SNC00100" src="http://igoro.com/wordpress/wp-content/uploads/2009/11/SNC00100.jpg" width="512" height="384" /></p>
]]></content:encoded>
			<wfw:commentRss>http://igoro.com/archive/video-of-my-plinq-session-at-pdc-2009/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
<enclosure url="http://ecn.channel9.msdn.com/o9/pdc09/wmvhigh/FT21.wmv" length="720490561" type="video/x-ms-wmv" />
<enclosure url="http://ecn.channel9.msdn.com/o9/pdc09/wmv/FT21.wmv" length="105056918" type="video/x-ms-wmv" />
		</item>
		<item>
		<title>Most Common Performance Issues in Parallel Programs</title>
		<link>http://igoro.com/archive/most-common-performance-issues-in-parallel-programs/</link>
		<comments>http://igoro.com/archive/most-common-performance-issues-in-parallel-programs/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 08:15:34 +0000</pubDate>
		<dc:creator>Igor Ostrovsky</dc:creator>
				<category><![CDATA[Concurrency]]></category>

		<guid isPermaLink="false">http://igoro.com/archive/most-common-performance-issues-in-parallel-programs/</guid>
		<description><![CDATA[Performance of parallel programs is an interesting &#8211; but also tricky &#8211; issue. I put together an article for our team blog that talks about the most common reasons why a parallel program may not scale as desired: Developers ask why one program shows a parallel speedup but another one does not, or how to [...]]]></description>
			<content:encoded><![CDATA[<p>Performance of parallel programs is an interesting &#8211; but also tricky &#8211; issue. I put together an article for our <a href="http://blogs.msdn.com/pfxteam/">team blog</a> that talks about the most common reasons why a parallel program may not scale as desired:</p>
<blockquote><p>Developers ask why one program shows a parallel speedup but another one does not, or how to modify a program so that it scales better on multi-core machines.
<p>The answers tend to vary. In some cases, the problem observed is a clear issue in our code base that is relatively easy to fix. In other cases, the problem is that Parallel Extension does not adapt well to a particular workload. This may be harder to fix on our side, but understanding real-world workloads is a first step to do that, so please continue to send us your feedback. In yet another class of issues, the problem is in the way the program uses Parallel Extensions, and there is little we can do on our side to resolve the issue.
<p>Interestingly, it turns out that there are common patterns that underlie most performance issues, regardless of whether the source of the problem is in our code or the user code. In this blog posting, we will walk though the common performance issues to take into consideration while developing applications using Parallel Extensions.</p>
</blockquote>
<p><a href="http://blogs.msdn.com/pfxteam/archive/2008/08/12/8849984.aspx">Read the rest of the article here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://igoro.com/archive/most-common-performance-issues-in-parallel-programs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Big Oh in the parallel world</title>
		<link>http://igoro.com/archive/big-oh-in-the-parallel-world/</link>
		<comments>http://igoro.com/archive/big-oh-in-the-parallel-world/#comments</comments>
		<pubDate>Mon, 11 Aug 2008 07:34:29 +0000</pubDate>
		<dc:creator>Igor Ostrovsky</dc:creator>
				<category><![CDATA[Concurrency]]></category>

		<guid isPermaLink="false">http://igoro.com/archive/big-oh-in-the-parallel-world/</guid>
		<description><![CDATA[Big-Oh notation is a simple and powerful way to express how running time of a particular algorithm depends on the size of the input. When you say that a particular algorithm runs in O(N2) time, you mean that the number of steps the algorithm takes is proportional to the input size squared. Or, in mathematical [...]]]></description>
			<content:encoded><![CDATA[<p>Big-Oh notation is a simple and powerful way to express how running time of a particular algorithm depends on the size of the input. When you say that a particular algorithm runs in O(N<sup>2</sup>) time, you mean that the number of steps the algorithm takes is proportional to the input size squared. Or, in mathematical terms, there is some fixed constant C, such that to process input of size N, the algorithm needs at most C x N<sup>2</sup> steps. One interesting question is how to define a &#8220;step&#8221;. The beauty of the Big-Oh notation is that any somewhat reasonable definition of a step will do. The step could be a clock cycle, a hardware instruction, or an expression in source code. If an algorithm takes O(N) steps according to one definition of a &#8220;step&#8221;, it takes O(N) according to all reasonable definitions.</p>
<p>While this is great, you already probably heard it a thousand times. But, what about the complexity of parallel programs? A major departure from the sequential case is that the number of steps an algorithm takes and the actual real-world time may not be proportional. In the parallel case, we may have potentially many cores executing the computation steps!</p>
<p><span id="more-71"></span></p>
<p>In fact, the number of computational cores is a new variable that we need to take into account. There are several ways to incorporate this variable into the Big-Oh notation, and I am going to describe them one-by-one.</p>
<p><strong>Method 1: &#8220;the algorithm runs in O(N) time in parallel&#8221;</strong></p>
<p>The crudest approach is simply to assume that there will be enough processors available on the machine, regardless of what &#8220;enough&#8221; means. Even this approximation tells us something deep about a particular algorithm. If the algorithm runs in O(N) time sequentially but in O(log N) in parallel, that means that the algorithm parallelizes well. On the other hand, if the algorithm runs in O(N) both sequentially and in parallel, then a large number of cores will probably not make the algorithm run much faster.</p>
<p>For example, consider the standard algorithm for multiplication of square matrices:</p>
<pre class="code"><span style="color: blue">static int</span>[,] Multiply(<span style="color: blue">int</span>[,] matrix1, <span style="color: blue">int</span>[,] matrix2) {
    <span style="color: blue">int </span>N = matrix1.GetLength(0);
    <span style="color: blue">int</span>[,] result = <span style="color: blue">new int</span>[N, N];

    <span style="color: blue">for </span>(<span style="color: blue">int </span>i = 0; i &lt; N; i++) {
        <span style="color: blue">for </span>(<span style="color: blue">int j</span> = 0; j &lt; N; j++) {
            <span style="color: blue">for </span>(<span style="color: blue">int </span>k = 0; k &lt; N; k++) {
                result[j, k] += matrix1[j, i] * matrix2[i, k];
            }        }    }

    <span style="color: blue">return </span>result;
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>If we have enough cores, the iterations of the loop over parameter j can execute in parallel, and so can iterations over parameter k. In fact, if we had a matrix of processors of size j * k, each of them would have to only perform one multiplication and one addition for each iteration of the parameter i, bringing down the running time to O(N).</p>
<p>So, in theory, we can say that provided that on a parallel machine, the program runs in O(N) time. There are two problems with that statement:</p>
<ol>
<li>We may need a lot of processors to achieve the O(N) running time. To multiply two 100&#215;100 matrices, we would need a machine with a 10,000 processors. 
<li>Today&#8217;s mainstream CPUs tends to perform poorly in cases where threads have to wait on each other a lot. In the matrix multiplication example, each thread would perform one multiplication and one addition and then have to wait. This would result in terrible performance in practice. On the other hand, SIMD hardware such as GPUs could potentially do much better.</li>
</ol>
<p><strong>Method 2: &#8220;the algorithm runs in O(N<sup>2</sup>) time with O(N) processors, or O(N) with O(N<sup>2</sup>) processors&#8221;</strong></p>
<p>To address the first of the two problems I mentioned, we can use the Big-Oh notation to also express the upper limit on the number of processors required to achieve a particular running time. For example, we can say that the matrix multiplication algorithm runs in O(N<sup>2</sup>) time on a machine with O(N) processors, or in O(N) time on a machine with O(N<sup>2</sup>) processors.</p>
<p>Now, we are not only saying how fast a program can run on a parallel machine, but also how many processors do we need to get there.</p>
<p><strong>Method 3: &#8220;the algorithm runs in O(N<sup>3</sup>/P) time, so long as P is in O(N<sup>2</sup>)&#8221;</strong></p>
<p><strong></strong></p>
<p>Finally, my favorite way to express complexity of a parallel algorithm is to introduce a new parameter P that represents the number of cores on a machine. For example, we would say that the matrix multiplication algorithm runs in O(N<sup>3</sup>/P) time. For completeness, we should also say that this only holds so long as P is in O(N<sup>2</sup>). After all, even if the computer has O(N<sup>3</sup>) cores, the matrix multiplication algorithm still cannot beat O(N).</p>
<p>One interesting thought exercise is to think about this: if the fastest possible sequential algorithm is O(F(N)), is it possible that there is a parallel algorithm which is asymptotically faster than O(F(N) / P) on a machine with P processors? If you you know the answer, let&#8217;s hear about it in the comments section!</p>
<p><strong>A few examples</strong></p>
<p>This table lists several sequential algorithms, and their parallel complexities using methods 1 and 3. Note that I don&#8217;t claim that each complexity listed in this table is optimal. A value in the table simply means that I am aware of an algorithm with this complexity. For example, I list the complexity of sequential matrix multiplication as O(N<sup>3</sup>), but there are somewhat faster algorithms out there.</p>
<table cellspacing="0" cellpadding="2" width="606" border="0">
<tbody>
<tr>
<td valign="top" width="152"><strong>Algorithm</strong></td>
<td valign="top" width="124"><strong>Sequential</strong></td>
<td valign="top" width="96"><strong>Method 1</strong></td>
<td valign="top" width="232"><strong>Method 3</strong></td>
</tr>
<tr>
<td valign="top" width="152">Sum, Max or <a href="http://en.wikipedia.org/wiki/Prefix_sum">Prefix sum</a></td>
<td valign="top" width="125">O(N)</td>
<td valign="top" width="98">O(log N)</td>
<td valign="top" width="232">O((N log N) / P), with P in O(N)<br />OR O(N / P) with P in O(sqrt N)</td>
</tr>
<tr>
<td valign="top" width="152">Edit distance</td>
<td valign="top" width="126">O(N^2)</td>
<td valign="top" width="99">O(N)</td>
<td valign="top" width="232">O(N<sup>2</sup> / P), with P in O(N)</td>
</tr>
<tr>
<td valign="top" width="151">Sorting</td>
<td valign="top" width="127">O(N log N)</td>
<td valign="top" width="100">O((log N)<sup>2</sup>)</td>
<td valign="top" width="232">O(N (log N)<sup>2</sup>/P), with P in O(N)</td>
</tr>
<tr>
<td valign="top" width="152">Matrix multiplication, <a href="http://en.wikipedia.org/wiki/Floyd_Warshall">Floyd Warshall</a></td>
<td valign="top" width="127">O(N<sup>3</sup>)</td>
<td valign="top" width="101">O(N)</td>
<td valign="top" width="232">O(N<sup>3</sup>/P), with P in O(N<sup>2</sup>)</td>
</tr>
<tr>
<td valign="top" width="151">Binary search</td>
<td valign="top" width="127">O(log N)</td>
<td valign="top" width="102">O(log N)</td>
<td valign="top" width="232">O(log N)</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://igoro.com/archive/big-oh-in-the-parallel-world/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Overview of concurrency in .NET Framework 3.5</title>
		<link>http://igoro.com/archive/overview-of-concurrency-in-net-framework-35/</link>
		<comments>http://igoro.com/archive/overview-of-concurrency-in-net-framework-35/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 08:22:08 +0000</pubDate>
		<dc:creator>Igor Ostrovsky</dc:creator>
				<category><![CDATA[Concurrency]]></category>

		<guid isPermaLink="false">http://igoro.com/archive/overview-of-concurrency-in-net-framework-35/</guid>
		<description><![CDATA[There is a lot of information on the concurrent primitives and concepts exposed by the .NET Framework 3.5 available on MSDN, blogs, and other websites. The goal of this post is to distill the information into an easy-to-digest high-level summary: what are the different pieces, where they differ and how they relate. If you want [...]]]></description>
			<content:encoded><![CDATA[<p>There is a lot of information on the concurrent primitives and concepts exposed by the .NET Framework 3.5 available on MSDN, blogs, and other websites. The goal of this post is to distill the information into an easy-to-digest high-level summary: what are the different pieces, where they differ and how they relate. If you want to know the difference between a Thread and a BackgroundWorker, or what is the point of interlocked operations, you are reading the right article.</p>
<p> <span id="more-65"></span>For each construct, I will give a motivating usage example and explain how it relates to other concurrent constructs.I will not attempt to cover everything there is to say about concurrent programming on .NET Framework, but whenever possible, I will link to more in-depth resources on each topic. <a href="http://www.amazon.com/gp/product/032143482X">Entire</a> <a href="http://www.amazon.com/gp/product/0321349601">books</a> have been written on concurrent programming for different platforms, so I certainly cannot fit everything into a single blog posting. But, I will walk you through the concurrent constructs and primitives so that you understand what is out there, and know where to look for more information if you need to.
</p>
<p>There are three key concepts that .NET concurrency primitives relate to: concurrent execution, synchronization and memory sharing. Let&#8217;s go over them one by one.</p>
<p><strong>Concurrent execution</strong></p>
<p>In order to move from sequential to concurrent programming, we need some way to do multiple things at the same time. In the .NET Framework, threads are the main mechanism for concurrent execution.</p>
<p>For example, this program reads integers from the console and factors them into primes, executing each factorization on a separate thread:</p>
<pre class="code"><span style="color: blue">static void </span>Factor(<span style="color: blue">long </span>x) {
    <span style="color: blue">var </span>factors = <span style="color: blue">new </span><span style="color: #2b91af">List</span>&lt;<span style="color: blue">long</span>&gt;();
    <span style="color: blue">for </span>(<span style="color: blue">long </span>i = 2; i * i &lt;= <span style="color: #2b91af">Math</span>.Abs(x); i++) {
        <span style="color: blue">while </span>(x % i == 0) {
            x /= i;
            factors.Add(i);
        }
    }

    <span style="color: blue">if </span>(x != 1 || factors.Count == 1) factors.Add(x);

    <span style="color: #2b91af">Console</span>.WriteLine(
        <span style="color: #a31515">&quot;{0} = {1}&quot;</span>,
        x,
        <span style="color: blue">string</span>.Join(<span style="color: #a31515">&quot; x &quot;</span>, factors.Select(i =&gt; i.ToString()).ToArray())); }
}</pre>
<p>The nice thing about this program is that even if some integer takes a long time to factor, the program will remain responsive. To see this, run the above program, and enter 100000000000000019. While the program is busy attempting to factor the large prime, you can continue to type in integers, and each answer pops up as soon as it is computed.</p>
<p>A disadvantage of the above approach is that if you use this program to factor many small integers, you will end up creating a lot of threads. Creation and destruction of threads is fairly expensive, so you will pay a significant performance cost. A thread pool is a construct to mitigate that cost. Instead of creating a new thread each time we want to perform some work asynchronously, we just enqueue the work on the thread pool. The thread pool keeps recycling the same threads to execute more and more work items, and thus avoids the cost of creating and destroying threads frequently. A thread pool is exposed in .NET via the <a href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx">ThreadPool</a> class. We can rewrite the Main method from the previous example to use ThreadPool instead of directly creating threads:</p>
<pre class="code"><span style="color: blue">static void </span>Main()
{
    <span style="color: blue">while </span>(<span style="color: blue">true</span>)
    {
        <span style="color: blue">string </span>line = <span style="color: #2b91af">Console</span>.ReadLine();
        <span style="color: blue">long </span>x = <span style="color: blue">long</span>.Parse(line);
        <span style="color: #2b91af">ThreadPool</span>.QueueUserWorkItem((o) =&gt; Factor(x));
    }
}</pre>
<p>Applications with a graphical user interface are one class of programs that benefit from concurrency. Frozen interface is a terrible user experience, and concurrent programming is one way to solve that problem. <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx">BackgroundWorker</a> is a class designed to make it easier to integrate asynchronous execution with application that use Windows Forms. BackgroundWorker provides the RunWorkerCompleted event that fire once all work is done, as well as the ProgressChanged to report periodically how much of the work has already been completed.</p>
<p>The main feature of the BackgroundWorker, and arguably the reason for its existence, is that events RunWorkerCompleted and ProgressChanged fire on the UI thread rather than on the thread on which the worker is executing. This is very important for integration with Windows Forms, because UI elements may only be modified from the UI thread. BackgroundWorker accomplishes this by posting messages from the worker thread, which get picked up by the event loop on the UI thread.</p>
<p><strong>Synchronization</strong></p>
<p>In most real-world usages, threads are not fully independent. Instead, they coordinate their progress and wait on each other at predetermined places. The mechanism for thread coordination is called synchronization.</p>
<p>The most important example of synchronization is mutual exclusion. Often, it is important to be able to ensure that two threads will not execute in some section of code at the same time. If one thread is executing in the critical section, and another thread attempts to enter that section, the second thread will have to wait until the first thread exits the critical section.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.aspx">Monitor</a> is the simplest primitive for mutual exclusion provided by the .NET framework. It allows any .NET object to be treated as a lock. Only one thread can be inside a region protected by a monitor which is associated with a particular object. However, note that two different threads can be inside two monitors which are associated with different objects. Here is an example that uses Monitor to implement a thread-safe Account class:</p>
<pre class="code"><span style="color: blue">class </span><span style="color: #2b91af">Account </span>{
    <span style="color: blue">private int </span>balance;
    <span style="color: blue">private object </span>myLock = <span style="color: blue">new object</span>();

    <span style="color: blue">public void </span>Deposit(<span style="color: blue">int </span>amount) {
        <span style="color: #2b91af">Monitor</span>.Enter(<span style="color: blue">this</span>.myLock);
        <span style="color: blue">try </span>{
            <span style="color: blue">this</span>.balance += amount;
        }
        <span style="color: blue">finally </span>{
            <span style="color: #2b91af">Monitor</span>.Exit(<span style="color: blue">this</span>.myLock);
        }
    }

    <span style="color: blue">public void </span>Withdraw(<span style="color: blue">int </span>amount) {
        <span style="color: #2b91af">Monitor</span>.Enter(<span style="color: blue">this</span>.myLock);
        <span style="color: blue">try </span>{
            <span style="color: blue">if </span>(<span style="color: blue">this</span>.balance &lt; amount) {
                <span style="color: blue">throw new </span><span style="color: #2b91af">InvalidOperationException</span>(<span style="color: #a31515">&quot;Balance too low.&quot;</span>);
            }
            <span style="color: blue">this</span>.balance -= amount;
        }
        <span style="color: blue">finally </span>{
            <span style="color: #2b91af">Monitor</span>.Exit(<span style="color: blue">this</span>.myLock);
        }
    }
}</pre>
<p>Since mutual exclusion using Monitor is such a common pattern, some .NET languages have a special language construct for it. C# is one of those languages, so we can rewrite the Withdraw() method from the Account class as follows:</p>
<pre class="code"><span style="color: blue">public void </span>Withdraw(<span style="color: blue">int </span>amount) {
    <span style="color: blue">lock </span>(myLock) {
        <span style="color: blue">if </span>(<span style="color: blue">this</span>.balance &lt; amount) {
            <span style="color: blue">throw new </span><span style="color: #2b91af">InvalidOperationException</span>(<span style="color: #a31515">&quot;Balance too low.&quot;</span>);
        }
        <span style="color: blue">this</span>.balance -= amount;
    }
}</pre>
<p>Mutual exclusion imposes a constraint that at most one thread executes in a particular critical section at a time. However, a looser synchronization pattern is often useful, where we distinguish between a read and write access to a critical section. Many readers can access the same critical section at the same time, but if a writer is in the critical section, all other readers and writers must stay out. As a result, throughput is improved if there are many more readers than writers, particularly on a multi-core machine.</p>
<p>This pattern of usage is supported by the <a href="http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx">ReaderWriterLock</a> class in the .NET framework. However, it turns out that the implementation of ReaderWriterLock has <a href="http://www.bluebytesoftware.com/blog/PermaLink,guid,54bf6c16-ce42-49d5-94db-aafbd7cb0c27.aspx">performance issues</a>, and as of version 3.0, .NET includes a new class <a href="http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx">ReaderWriterLockSlim</a>. Long story short, you should always use ReaderWriterLockSlim rather than ReaderWriterLock.</p>
<p>As an example, let&#8217;s implement another class to represent a bank account, this time with reader-writer locks:</p>
<pre class="code"><span style="color: blue">class </span><span style="color: #2b91af">Account2 </span>{
    <span style="color: blue">private int </span>balance;
    <span style="color: blue">private int </span>overdraftLimit;
    <span style="color: #2b91af">ReaderWriterLockSlim </span>rwLock = <span style="color: blue">new </span><span style="color: #2b91af">ReaderWriterLockSlim</span>();

    <span style="color: blue">public </span>Account2(<span style="color: blue">int </span>balance, <span style="color: blue">int </span>overdraftLimit) { ... }

    <span style="color: blue">public void </span>SetOverdraftLimit(<span style="color: blue">int </span>overdraftLimit) { ... }

    <span style="color: blue">public void </span>Deposit(<span style="color: blue">int </span>overdraftLimit) { ... }

    <span style="color: blue">public void </span>Withdraw(<span style="color: blue">int </span>amount) {
        <span style="color: blue">this</span>.rwLock.EnterWriteLock();
        <span style="color: blue">try </span>{
            <span style="color: blue">if </span>(<span style="color: blue">this</span>.balance + <span style="color: blue">this</span>.overdraftLimit &lt; amount) {
                <span style="color: blue">throw new </span><span style="color: #2b91af">InvalidOperationException</span>(<span style="color: #a31515">&quot;Balance too low.&quot;</span>);
            }
            <span style="color: blue">this</span>.balance -= amount;
        }
        <span style="color: blue">finally </span>{
            <span style="color: blue">this</span>.rwLock.ExitWriteLock();
        }
    }

    <span style="color: blue">public int </span>GetBalance() {
        <span style="color: blue">this</span>.rwLock.EnterReadLock();
        <span style="color: blue">try </span>{
            <span style="color: blue">return this</span>.balance;
        }
        <span style="color: blue">finally </span>{
            <span style="color: blue">this</span>.rwLock.ExitReadLock();
        }
    }
}</pre>
<p>If calls to GetBalance() are much more frequent than calls to Deposit(), Withdraw() and SetOverdraftLimit(), we should observe a significant performance improvement from using ReaderWriterLockSlim over Monitor.</p>
<p>Reader-writer lock is one possible generalization of the mutual exclusion concept. Another possible generalization is to limit the number of threads executing in a critical section to a number larger than one. This problem certainly does not arise as frequently as the critical section problem, but it is frequent enough to be addressed by a classic computer science construct known as a semaphore. In .NET, semaphores are exposed via the <a href="http://msdn.microsoft.com/en-us/library/system.threading.semaphore.aspx">Semaphore</a> class. This code sample implements method ThrottledQueryDB which limits the number of threads that can concurrently call QueryDB() to 5:</p>
<pre class="code"><span style="color: blue">class </span><span style="color: #2b91af">SemaphoreSample </span>{
    <span style="color: blue">private </span><span style="color: #2b91af">Semaphore </span>semaphore = <span style="color: blue">new </span><span style="color: #2b91af">Semaphore</span>(0, 5);

    <span style="color: blue">public void </span>ThrottledQueryDB() {
        semaphore.WaitOne();
        <span style="color: blue">try </span>{
            QueryDB();
        }
        <span style="color: blue">finally </span>{
            semaphore.Release();
        }
    }
}</pre>
<p>However, there are many synchronization scenarios that are more complicated than mutual exclusion. For example, we may want one thread to wait until another thread computes an result, and only proceed once the result is ready. Monitor&#8217;s methods Wait, Pulse and PulseAll are often the easiest way to implement this scenario. The nice thing about using Monitor&#8217;s methods is that Pulse and Wait are called while holding a lock. If we use events (described below) rather than Monitor signaling, it becomes much harder to avoid race conditions. Here is a simple implementation of a producer-consumer exchange data structure that has a capacity for one element, and blocks both consumers and producers as appropriate:</p>
<pre class="code"><span style="color: blue">class </span><span style="color: #2b91af">ProducerConsumer</span>&lt;T&gt; {
    <span style="color: blue">private </span>T value;
    <span style="color: blue">private bool </span>isEmpty = <span style="color: blue">true</span>;

    <span style="color: blue">public void </span>Produce(T t) {
        <span style="color: blue">lock </span>(<span style="color: blue">this</span>) {
            <span style="color: blue">while </span>(!isEmpty) {
                <span style="color: #2b91af">Monitor</span>.Wait(<span style="color: blue">this</span>);
            }
            <span style="color: blue">this</span>.value = t;
            isEmpty = <span style="color: blue">false</span>;
            <span style="color: #2b91af">Monitor</span>.Pulse(<span style="color: blue">this</span>);
        }
    }

    <span style="color: blue">public </span>T Consume() {
        <span style="color: blue">lock </span>(<span style="color: blue">this</span>) {
            <span style="color: blue">while </span>(isEmpty) {
                <span style="color: #2b91af">Monitor</span>.Wait(<span style="color: blue">this</span>);
            }

            isEmpty = <span style="color: blue">true</span>;
            <span style="color: #2b91af">Monitor</span>.Pulse(<span style="color: blue">this</span>);
            <span style="color: blue">return this</span>.value;
        }
    }
}</pre>
<p>An even more powerful construct than Monitor signaling is an event. In .NET, events are represented via the <a href="http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx">ManualResetEvent</a> and <a href="http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx">AutoResetEvent</a> classes. The main two operations on an event are WaitOne and Set. Various threads can &quot;wait&quot; on the event by calling WaitOne. Each call to WaitOne will block, until some other thread calls Set, at which point all threads that have been waiting on the event wake up. The difference between the two events is that AutoResetEvent automatically resets into the &quot;unset&quot; state itself after it has been set, while the ManualResetEvent can be reset manually by calling the Reset method.</p>
<p>For a usage example of events, see for example the MSDN article, <a href="How to: Synchronize a Producer and a Consumer Thread">How to: Synchronize a Producer and a Consumer Thread</a>.</p>
<p><strong>Memory sharing</strong></p>
<p>I talked about how to run code on different threads, and also how to synchronize them. One thing that I did not talk about is how to access shared memory from different threads.</p>
<p>First, the nice part: if all reads and writes to a particular memory location are protected by <strong>the same</strong> lock, each read will see the most up-to-date value written to that memory location. Reads and writes will behave exactly as you would expect. That is pretty nice and simple, and in 99% of cases, all that you need.</p>
<p>But, once we leave the safety of locks and attempt to access the same memory from multiple threads, things get much, much more complicated. I won&#8217;t get into details here, but in summary: many properties that we take for granted in single-threaded programming (and get for free in multi-threaded programming with proper locking) break down when we try to share memory among threads without locking. Reads and writes may get reordered in strange ways. For example, if one thread updates value X and then updates value Y, and another thread reads value Y and then value X, the reader thread may see the new value of X, but not the new value of Y. Or, one thread may set a flag, and another thread may loop forever checking the flag, never finding out that the flag has in fact already been set.</p>
<p>If you want to use low-lock techniques, you need to precisely understand the guarantees that the CLR makes about memory operations in situations where multiple threads access the same memory without locking. This is not for the faint at heart, but if you are interested, you can read up on the CLR memory model in Vance Morrison&#8217;s <a href="http://msdn.microsoft.com/en-us/magazine/cc163715.aspx">article</a>.</p>
<p>As I said, low-lock techniques are hard. Despite that, it is useful to know what is out there. So, let&#8217;s move on to describe the constructs offered by the framework.</p>
<p>One technique to avoid locking is to take advantage of atomic operations exposed as static methods on the <a href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.exchange.aspx">Interlocked</a> class. These atomic operations are available:</p>
<ul>
<li>Add: given two integers, replaces the first one with their sum, and returns the sum. </li>
<li>CompareExchange: if a value is equal to a comparand, replaces it with another value. </li>
<li>Decrement: decrements an integer and returns the new value. </li>
<li>Exchange: sets a variable to some value. </li>
<li>Increment: increments an integer and returns the new value. </li>
<li>Read: reads a 64-bit value. </li>
</ul>
<p>Now, the operations on the above list may seem pretty uninteresting. The reason why they are useful is that they are atomic. The entire operation either takes place fully or not at all, and no other thread may observe the intermediate invalid state. That is a very nice property, typically difficult to achieve in low-lock situations.</p>
<p>For example, consider this Counter class:</p>
<pre class="code"><span style="color: blue">class </span><span style="color: #2b91af">Counter </span>{
    <span style="color: blue">int </span>count = 0;

    <span style="color: blue">public void </span>Increment() {
        <span style="color: #2b91af">Interlocked</span>.Increment(<span style="color: blue">ref </span>count);
    }

    <span style="color: blue">public int </span>Count {
        <span style="color: blue">get </span>{ <span style="color: blue">return </span>count; }
    }
}</pre>
<p>You could implement the same method by replacing the Interlocked.Increment(count) with count++. But, that would only work if all calls to the Increment method are externally synchronized. The ++ increment operator is a notorious example of a simple operation that is not atomic, and if multiple threads attempt to increment the same field at the same time, some increments may get lost, and an incorrect count will get computed. Interlocked.Increment provides an atomic increment operation that does not require locks, which can be very useful.</p>
<p>Another low-lock technique is the use of <a href="http://msdn.microsoft.com/en-us/library/aa645755(VS.71).aspx">volatile</a> fields. Some of the strange cases I mentioned earlier (such as a thread seeing a value written earlier, but not a value written later) go away when you mark the shared memory as volatile. Volatile fields prevent the some kinds of reordering from happening: no reads or writes can move before a volatile read, and no reads or writes can move after a volatile write. Understanding precisely what these restrictions allow you to assume in practice is unfortunately quite hard, but Vance Morisson&#8217;s <a href="http://msdn.microsoft.com/en-us/magazine/cc163715.aspx">article</a> helps.</p>
<p>If a field is volatile, then all reads and writes to that field will be volatile. To make a particular read of a non-volatile field volatile, use the <a href="http://msdn.microsoft.com/en-us/library/system.threading.thread.volatileread.aspx">VolatileRead</a> static method on the Thread class. <a href="http://msdn.microsoft.com/en-us/library/system.threading.thread.volatilewrite(VS.80).aspx">VolatileWrite</a> method is available as well, but due to some bizarre consequences of the .NET memory model, there is no difference between a volatile write and a regular write. At least, that is the case to the best of my knowledge, in .NET 3.5.</p>
<p>As I said earlier, volatile reads and writes prevent other reads and writes from moving across them in one direction. <a href="http://msdn.microsoft.com/en-us/library/system.threading.thread.memorybarrier.aspx">MemoryBarrier</a> method on the Thread class is creates a fence that cannot be crossed in either direction by reads or writes.</p>
<p>Finally, one construct that is quite often useful is a thread-local static field.&#160; A thread-local static field differs from regular static fields in that it can hold multiple values at the same time. Specifically, each thread has its own copy of the field that is completely independent from the copies that other threads see. Each thread can read and write into its own copy. To make a static field thread-local, mark it with the <a href="http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx">ThreadStatic</a> attribute.</p>
<p>This static class uses a thread-local field to track how many times each thread called the Register() method:</p>
<pre class="code"><span style="color: blue">static class </span><span style="color: #2b91af">ThreadAccessCounter </span>{
    [<span style="color: #2b91af">ThreadStatic</span>]
    <span style="color: blue">private <span style="color: blue">static</span> int </span>count;

    <span style="color: blue">public static void </span>Register() {
        count++;
        <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">&quot;This thread has called Register() {0} times&quot;</span>, count);
    }
}</pre>
<p><strong>Comments and Conclusion</strong></p>
<p>These are the most important concurrency constructs and primitives in .NET 3.5&#8230; quite a list! And, that list does not even include Parallel Extensions, the <a href="http://blogs.msdn.com/pfxteam/archive/2008/06/02/8567093.aspx">community technology preview</a> of which was released two weeks ago. (For those unaware, I am a developer at the Microsoft team developing Parallel Extensions.)</p>
<p>As is usual, all code samples in this posting are provided as-is, with no guarantees.</p>
<p><strong>Related</strong></p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/1c9txz50.aspx">Managed Threading Best Practices</a> [msdn.microsoft.com] covers concurrency gotchas and how to avoid them, which is something I did not get to in this article. </li>
<li><a href="http://www.amazon.com/gp/product/0596527578?ie=UTF8&amp;tag=igorostrblog-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596527578">C# 3.0 in a Nutshell</a> [book] contains an in-depth chapter on concurrency. The chapter is also available <a href="http://www.albahari.com/threading/">online</a>. </li>
<li><a href="http://www.amazon.com/gp/product/032143482X?ie=UTF8&amp;tag=igorostrblog-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=032143482X">Concurrent Programming on Windows Vista</a> [book] is available for pre-order, and will be an excellent resource for concurrency on Windows and .NET. </li>
</ul>
<p><a style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2figoro.com%2farchive%2foverview-of-concurrency-in-net-framework-35%2f"><img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2figoro.com%2farchive%2foverview-of-concurrency-in-net-framework-35%2f" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://igoro.com/archive/overview-of-concurrency-in-net-framework-35/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>
