<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>the Void</title>
	
	<link>http://blog.ashodnakashian.com</link>
	<description>Thoughts of an Earthling</description>
	<lastBuildDate>Fri, 03 May 2013 13:47:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ashodnakashian/zpMw" /><feedburner:info uri="ashodnakashian/zpmw" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>ashodnakashian/zpMw</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Guns, Cars and Stalin</title>
		<link>http://feedproxy.google.com/~r/ashodnakashian/zpMw/~3/yeZF-Zw5PGw/</link>
		<comments>http://blog.ashodnakashian.com/2013/05/guns-cars-and-stalin/#comments</comments>
		<pubDate>Fri, 03 May 2013 13:47:16 +0000</pubDate>
		<dc:creator>Ashod Nakashian</dc:creator>
				<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Politics]]></category>
		<category><![CDATA[Bad Arguments]]></category>
		<category><![CDATA[Guns]]></category>
		<category><![CDATA[Responsibility]]></category>

		<guid isPermaLink="false">http://blog.ashodnakashian.com/?p=2218</guid>
		<description><![CDATA[I was probably never going cross paths with or hear about the five-year-old boy who shot his two-year-old sister dead, nor any of her parents. Odds are, most people on the planet wouldn&#8217;t know about them had it not been for the story that hit the news. Unbeknownst to me, I had gotten in an argument <a href='http://blog.ashodnakashian.com/2013/05/guns-cars-and-stalin/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>I was probably never going cross paths with or hear about the five-year-old boy who shot his <a href="http://www.cnn.com/2013/05/01/us/kentucky-accidential-shooting/index.html">two-year-old sister dead</a>, nor any of her parents. Odds are, most people on the planet wouldn&#8217;t know about them had it not been for the story that hit the news.</p>
<p>Unbeknownst to me, I had gotten in an argument with a pro-gun who hid his affection rather well, all the while I thought we were having a casual conversation.  As tragic as this is, and as a parent I can identify with the grief of losing a child. But I cannot feel sad any more than I can understand what a parent must feel knowing it wasn&#8217;t an accident out of their control, rather it was precisely a consequence of their upbringing. &#8220;No, it&#8217;s sad. It&#8217;s very sad.&#8221; I was told. To me sad is that <a href="http://www.guardian.co.uk/society/sarah-boseley-global-health/2010/may/12/infant-mortality-millennium-development-goals">nearly</a> <a href="http://www.who.int/maternal_child_adolescent/documents/pdfs/lancet_child_survival_10mill_dying.pdf">9 million</a> <a href="http://en.wikipedia.org/wiki/Child_mortality">child dies</a> every single year of malnutrition and other trivially-curable complications or diseases, I answered. &#8220;You aren&#8217;t sad for the 9 million dying children?&#8221;</p>
<blockquote><p>No, I&#8217;m not sad. You know what Stalin said? He said, &#8216;<strong>a single death is sad, millions dead is a statistic.</strong>&#8216;</p></blockquote>
<p>Yes, that was the response I got.</p>
<p>And before I knew it, I got the argument for guns: <strong>Cars kill more people than guns, but you don&#8217;t want to ban cars, do you?</strong></p>
<p>Before we get too worked up, let&#8217;s separate these two points: Emotions developed on hearing stories of unknown individuals, as tragic as they may be, is one thing, not having good arguments to defend a position and instead repeating bad arguments is a completely different matter.</p>
<h2>Hume Rolls in his Grave</h2>
<p>Kentucky State Police Trooper, Billy Gregory, said &#8220;in this part of the country, it&#8217;s not uncommon for a five-year-old to have a gun or for a parent to pass one down to their kid.&#8221; Regardless of whether I am pro gun or not, I must recognize one thing: <em>Guns are dangerous</em>.</p>
<p>&#8220;Passing down&#8221; guns to a five-year-old inherently and inevitably implies taking a certain risk. The risk of the gun going off, whether intentionally or accidentally. Failing to recognize this simple fact is akin to covering one&#8217;s face when losing control of their car. There might be multiple ways to resolve a problem, but ignoring it couldn&#8217;t be one of them.</p>
<p>If I start drinking and gambling, I shouldn&#8217;t expect anyone to be surprised when I lose everything and end up on the streets. I shouldn&#8217;t expect anyone to feel sad for my stupidity and bad choices. They might as well laugh at my surprise at the outcome. If I hand my twelve-year-old the car keys, should I or anyone else find it odd when they crash the car and damage people and property? Should I expect pity from others if the car crashes into my house damaging and injuring me?  Similarly, guns and children do not produce an infinite output of combinations: there are <a href="http://www.cnn.com/2013/04/24/health/kids-guns-study/index.html">very few things</a> that we should <a href="http://www.cnn.com/2013/04/09/us/tennessee-gun-death/index.html">expect</a> to <a href="http://www.cnn.com/2013/04/09/us/new-jersey-child-shooting/index.html">happen</a> from the marriage and we only hope it&#8217;s going to be playground fun. But <em>hoping is no precaution</em>.</p>
<p>I find it borderline humorous that people systematically give their children guns and then the whole world is gaping at the death of a child. I find it inevitable, unless steps are taken to prevent it. Like everyone else, I have limited energy, both emotionally and otherwise, and I prefer to spend them on preventable causes that affect countless more children, equally fragile, equally lovable and equally rightful to life.</p>
<p>Just because we find it easier to write off millions of deaths to statistics doesn&#8217;t make it right. I&#8217;m sure Stalin had other apt utterance worthy of quoting in the light of the massacres, deportations and cold-blood killings that he sanctioned. But should we take comfort in the coldness of the indifference that we may feel at the death of millions of children who, like the victim in this case, haven&#8217;t yet seen their fifth birthday? Does Stalin&#8217;s ludicrous indifference have any bearing on how one feels or should feel?</p>
<p>Stalin&#8217;s quote was at once shocking and baffling to me. I didn&#8217;t know if using it was an excuse and justification for one&#8217;s feelings, or lack thereof, or it was a Freudian slip. Either way, just because something <a href="http://en.wikipedia.org/wiki/Is%E2%80%93ought_problem"><em>is</em> doesn&#8217;t imply what it <em>ought</em></a> to be, morally speaking. Perhaps we should start feeling sad about these children of have-not parents. The children dying of famine have only nature and our inaction to blame. The five-year-old who killed his sister, in contrast, has his parents to blame for preferring to buy him a gun (or at least allowing him to own one) instead of a multitude other things they could have done, not least buying him a book to read and learn from in the hope of bettering himself and his society.</p>
<p>I cannot feel sad for the decisions of others, any more than I can prevent them from taking these decisions. However the same couldn&#8217;t be said of the children dying of malnutrition and lack of clean water. In the later case I <em>can</em> prevent it, and my (collectively our, really) inaction to save a single more child is sad indeed.</p>
<p>At least in one sense he was right, though. We cannot begin to imagine anything in the millions, but a single child with a picture in the news is readily reachable. But that only speaks of our limitations of being human, and hopefully not of our inhumanity.</p>
<h2>Guns and Cars</h2>
<p>I have heard many decent arguments for crazy things, including keeping slaves and leaving women out of the workforce (and typically in the kitchen) among others. Here &#8220;decent&#8221; doesn&#8217;t mean acceptable or justifiable, rather that the point in an of itself having a merit. They fail because taken in the full context of the issue, a single argument for or against something as complex as these topics doesn&#8217;t simply have enough weight.</p>
<p>Slavery had many benefits to slaves, not least steady income, job security and living space. And at least some women will not mind if given half a chance to be relieved of the burden of providing for oneself and their family entails. Women aren&#8217;t unique in wishing for an easier lifestyle than working forty-hour-weeks.</p>
<p>But these arguments fail to resolve the issue one way or the other because they are incomplete. They shed light on a single aspect and it&#8217;s a very narrow one at that as well. Cars do kill people, perhaps much more people than guns (clearly here we are ignoring wars). I&#8217;ve read numbers as high as 500,000 annual deaths from car accidents.</p>
<p>Do I want to ban cars for this huge loss that they cause? Yes, and in a sense we <em>do</em> already. The traffic and car licensing laws have evolved in response to both the dangers that are inherent in driving and the exploding number of cars and motorists. Driving under the influence of alcohol (given a certain allowance, if at all) is a grave offense in many states and countries and can be a felony if others are injured. Multiple offenses typically result in revoking the license and often sentencing to jail.</p>
<p>More importantly, the argument is weak and irrelevant because it appeals to one&#8217;s disposition, bias and shortcomings of undermining the perils of cars. Indeed, many of us cringe upon hearing about spiders and snakes, let alone seeing one, but may jaywalk in heavy traffic, sometimes with children.</p>
<p>We should avoid driving whenever we can and we should have better laws, education, responsible drivers and car owners as well as better traffic rules to minimize their risks. But we should also do the same for guns. Giving them to kids should simply be an offense no less sever than letting a minor drive your car. Having a gun gifted to a child, by maker called &#8220;My first rifle,&#8221; and then pretending that the gun will be locked in a safe is simply avoiding to see things for what they are. Children are attached to their toys and I guess that&#8217;s the point of manufacturing guns for them in the first place &#8211; they are expected to become loyal gun owners for many more years.</p>
<p>All this pretending that guns have benefits to society on equal footing to cars to justify their risks. I am not willing to give such a blank license to cars and will demand improving the situation to avoid unnecessary injury and loss of life from car accidents. But the onus for proving the benefits of guns to be even remotely comparable to those of cars is certainly not on me. Let alone the benefit of guns to <em>kids</em>.</p>
<p>When someone kills another with their car, they cannot claim that injury is a risk we&#8217;ve come to accept, so why prosecute them anymore than a gun owner can claim the same. But let&#8217;s not pretend that owning guns is a right without restrictions, because being responsible is all about restrictions, first to oneself before others.</p>
<p><em><strong>We will never take responsibility if we don&#8217;t see the inherent dangers of our choices and if we don&#8217;t understand that both car and gun deaths are preventable and they are both of our choosing, and as long as we view our actions vicariously.</strong></em></p>
<p>Evidently, the grandmother of the now-dead two-year-old has a different understanding of cause and effect than mind. &#8220;It was God&#8217;s will. It was her time to go, I guess, I just know she&#8217;s in heaven right now and I know she&#8217;s in good hands with the Lord.&#8221; She said.</p>
<p>I feel sorry for the five-year-old for having the parents he has, and I can only hope he will not repeat the same mistakes when the roles are reversed.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.ashodnakashian.com%2F2013%2F05%2Fguns-cars-and-stalin%2F&amp;title=Guns%2C%20Cars%20and%20Stalin" id="wpa2a_2"><img src="http://blog.ashodnakashian.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=yeZF-Zw5PGw:q-9xIeDz2R4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=yeZF-Zw5PGw:q-9xIeDz2R4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=yeZF-Zw5PGw:q-9xIeDz2R4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=yeZF-Zw5PGw:q-9xIeDz2R4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=yeZF-Zw5PGw:q-9xIeDz2R4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=yeZF-Zw5PGw:q-9xIeDz2R4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=yeZF-Zw5PGw:q-9xIeDz2R4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=yeZF-Zw5PGw:q-9xIeDz2R4:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=yeZF-Zw5PGw:q-9xIeDz2R4:l6gmwiTKsz0"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=l6gmwiTKsz0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=yeZF-Zw5PGw:q-9xIeDz2R4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ashodnakashian/zpMw/~4/yeZF-Zw5PGw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.ashodnakashian.com/2013/05/guns-cars-and-stalin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ashodnakashian.com/2013/05/guns-cars-and-stalin/</feedburner:origLink></item>
		<item>
		<title>15% Newark/Element14 Discount Voucher and Raspberry Pi</title>
		<link>http://feedproxy.google.com/~r/ashodnakashian/zpMw/~3/HLxbipvT2vM/</link>
		<comments>http://blog.ashodnakashian.com/2013/04/15-newarkelement14-discount-voucher-and-raspberry-pi/#comments</comments>
		<pubDate>Sat, 20 Apr 2013 17:40:01 +0000</pubDate>
		<dc:creator>Ashod Nakashian</dc:creator>
				<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Newark/Element14]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Voucher]]></category>

		<guid isPermaLink="false">http://blog.ashodnakashian.com/?p=2205</guid>
		<description><![CDATA[I just got my Raspberry Pi a couple of weeks ago from Newark/Element14. First impressions are great! All I needed was an SD card and the HDMI cable that came with the TV set. Downloaded &#8220;wheezy&#8221; and placed on the SD card. Hooked my favorite toy, the &#8220;remote control&#8221; (a.k.a. Logitech K400) and I had a complete <a href='http://blog.ashodnakashian.com/2013/04/15-newarkelement14-discount-voucher-and-raspberry-pi/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>I just got my <a href="http://www.raspberrypi.org/">Raspberry Pi</a> a couple of weeks ago from <a href="http://canada.newark.com/jsp/bespoke/bespoke7.jsp?bespokepage=newark/en_US/landing/raspberry-pi/rasp-pi-accessories.jsp&amp;isRedirect=true">Newark/Element14</a>. First impressions are great!</p>
<p>All I needed was an SD card and the HDMI cable that came with the TV set. Downloaded <a href="http://www.raspberrypi.org/downloads">&#8220;wheezy&#8221;</a> and placed on the SD card. Hooked my favorite toy, the &#8220;remote control&#8221; (a.k.a. <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16823126264">Logitech K400</a>) and I had a complete system with little effort. I hooked a mini USB cable from the Pi to the TV to power it. Flawless first boot.</p>
<p>Out of the box it has everything essential, including web browser<em>s</em>, Python Idle and a <a href="http://scratch.mit.edu/">Scratch</a> - a puzzle-like game development platform that the kids love. Hooking a Cat5 to the router and internet. Apt-getting mplayer and <a href="http://www.gnu.org/software/gnash/">Gnash</a> (open flash player). Video is unusable without the hardware acceleration, which requires <a href="http://www.raspberrypi.com/">license fees</a> to enable the codecs, though. However <a href="http://www.shoutcast.com/">internet radio</a> is very much within reach. Depending on the bitrate and codec, it uses anywhere between 25% to 75% of CPU cycles. Oh, and I had to get the stream IP from the .pls files on shoutcast, but that&#8217;s trivial to wrap in a script that wget, sed and spawns mplayer.</p>
<p>As a toy, experimentation lab/playground, Swiss Army knife embedded system, or educational platform, it&#8217;s very hard to beat. At $25 for model A and $35 for model B, it does more than it costs.</p>
<p>I couldn&#8217;t be happier with exchanging my hard earned cash with the Pi, so you can imagine my surprise when I got a call from Newark to ask about the feedback on the delivery and my order  (both of which were fantastic) and was asked if I minded that if they sent me a discount code on my mail. To top it off, I was encouraged to share them with you.</p>
<p>Here is a snippet of the thank-you email:</p>
<blockquote><p>Thank you for your most recent order! We appreciate your business and as a thank you we would like to extend to you a 15% off voucher. The Voucher code is THANKS1C and it can be used as many times as you would like through April 30th, 2013. After May 1st, use code THANKS2 which is good through June 1st 2013. Feel free to share with whomever you would like.  When placing an order over our website, please type in the voucher code on the shopping cart page. If you are ordering by phone, simply give the code to the representative processing your order. There are lots of ways to take advantage of this limited offer from our award winning website <a id="yui_3_7_2_1_1366412791021_2295" href="http://canada.newark.com/" target="_blank">http://canada.newark.com</a>  to our knowledgeable and friendly team waiting to take your call at 1 800 463 9275. You may also send your quote to <span class="mh-email">quo<a href='http://www.google.com/recaptcha/mailhide/d?k=01N3PBm-QDT_F8MUoL-78ALw==&amp;c=79X50igktYTYzPZ7SAY3yYXCdIFsFtCa-UBeeIe_dhc=' onclick="window.open('http://www.google.com/recaptcha/mailhide/d?k=01N3PBm-QDT_F8MUoL-78ALw==&amp;c=79X50igktYTYzPZ7SAY3yYXCdIFsFtCa-UBeeIe_dhc=', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;" title="Reveal this e-mail address">...</a>@newark.com</span> or email a purchase order to <span class="mh-email">ord<a href='http://www.google.com/recaptcha/mailhide/d?k=01N3PBm-QDT_F8MUoL-78ALw==&amp;c=70XO0yJyhKie8AKSldw3wcf1biPDGr8SA7GM6AAaPEc=' onclick="window.open('http://www.google.com/recaptcha/mailhide/d?k=01N3PBm-QDT_F8MUoL-78ALw==&amp;c=70XO0yJyhKie8AKSldw3wcf1biPDGr8SA7GM6AAaPEc=', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;" title="Reveal this e-mail address">...</a>@newark.com</span>.</p></blockquote>
<p style="text-align: center;"><strong>THANKS1C</strong> (through <em>April 30th</em>, 2013)</p>
<p style="text-align: center;"><strong>THANKS2</strong> (from <em>May 1st</em> through <em>June 1st</em> 2013)</p>
<p>Note:</p>
<blockquote><p>Discount applies to the first price-break quantities only. Discount cannot be combined with other offers, promotions, quantity discounts, or contract pricing. Contractual considerations with a small number of manufactures may reduce or prevent a voucher discount on selected items including test equipment; Cannot be used on Raspberry PI. call us with questions relating to voucher exclusions. Non-catalog items are not subject to a voucher discount.</p></blockquote>
<p>It&#8217;s reasonable that the discount doesn&#8217;t apply to the Pi, considering that it&#8217;s a non-profit and sold at cost price. So, share them, use them and hope you give Raspberry Pi a spin and let me hear your thoughts. It&#8217;s well worth it.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.ashodnakashian.com%2F2013%2F04%2F15-newarkelement14-discount-voucher-and-raspberry-pi%2F&amp;title=15%25%20Newark%2FElement14%20Discount%20Voucher%20and%20Raspberry%20Pi" id="wpa2a_4"><img src="http://blog.ashodnakashian.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=HLxbipvT2vM:mLdj5pymqeA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=HLxbipvT2vM:mLdj5pymqeA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=HLxbipvT2vM:mLdj5pymqeA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=HLxbipvT2vM:mLdj5pymqeA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=HLxbipvT2vM:mLdj5pymqeA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=HLxbipvT2vM:mLdj5pymqeA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=HLxbipvT2vM:mLdj5pymqeA:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=HLxbipvT2vM:mLdj5pymqeA:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=HLxbipvT2vM:mLdj5pymqeA:l6gmwiTKsz0"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=l6gmwiTKsz0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=HLxbipvT2vM:mLdj5pymqeA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ashodnakashian/zpMw/~4/HLxbipvT2vM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.ashodnakashian.com/2013/04/15-newarkelement14-discount-voucher-and-raspberry-pi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ashodnakashian.com/2013/04/15-newarkelement14-discount-voucher-and-raspberry-pi/</feedburner:origLink></item>
		<item>
		<title>Async I/O and ThreadPool Deadlock (Part 5)</title>
		<link>http://feedproxy.google.com/~r/ashodnakashian/zpMw/~3/RyNyh7HPFN4/</link>
		<comments>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-5/#comments</comments>
		<pubDate>Mon, 08 Apr 2013 06:46:57 +0000</pubDate>
		<dc:creator>Ashod Nakashian</dc:creator>
				<category><![CDATA[Code Snippet]]></category>
		<category><![CDATA[From the Trenches]]></category>
		<category><![CDATA[Guides]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Deadlock]]></category>
		<category><![CDATA[Leaky Abstraction]]></category>
		<category><![CDATA[Parallelization]]></category>
		<category><![CDATA[Pipes]]></category>
		<category><![CDATA[Threading]]></category>
		<category><![CDATA[ThreadPool]]></category>
		<category><![CDATA[Win32]]></category>

		<guid isPermaLink="false">http://blog.ashodnakashian.com/?p=2147</guid>
		<description><![CDATA[In part 4 we&#8217;ve replaced Parallel.ForEach with Task. This allowed us run the processes on the ThreadPool threads, but waited only in the main thread. So the worker threads were never blocked on waits. They executed the child process, then processed the output callbacks and exited promptly. All the while, the main thread is waiting <a href='http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-5/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://blog.ashodnakashian.com/?p=2117">In part 4</a> we&#8217;ve replaced <code>Parallel.ForEach</code> with <code>Task</code>. This allowed us run the processes on the <code>ThreadPool</code> threads, but waited only in the main thread. So the worker threads were never blocked on waits. They executed the child process, then processed the output callbacks and exited promptly. All the while, the main thread is waiting for everything to finish completely. To do this, we needed to both break the <code>Run</code> logic from the <code>Wait</code>. In addition, we had to keep the <code>Process</code> instances alive for the callbacks to work and we can detect the end correctly.<br />
<br />
This worked well for us. Except for the nagging problem that we can&#8217;t use <code>Parallel.ForEach</code>. Or rather, if we did, even accidentally, we&#8217;d deadlock as we did before. Also, our wrapper isn&#8217;t readily reusable in other classes without explicitly separating the <code>Run</code> call from the <code>Wait</code> on separate threads as we did. Clearly this isn&#8217;t a bulletproof solution.</p>
<p>It might be tempting to think that the <code>Process</code> class is a thin wrapper around the OS process, but in fact it&#8217;s rather complex. It does a lot for us, and we shouldn&#8217;t throw it away. It&#8217;d be great if we could avoid the problem with <code>ThreadPool</code> altogether. Remember the reason we&#8217;re using it was because the synchronous version deadlocked as well.</p>
<p>What if we could improve the synchronous version?</p>
<h2>Synchronous I/O Take 2</h2>
<p>Recall that the deadlock happened because to read until the end of the output stream, we need to wait for the process to exit. The process, in its turn, wouldn&#8217;t exit until it has written all its output, which we&#8217;re reading. Since we&#8217;re reading only one stream at a time (either <code>StandardOutput</code> or <code>StandardError</code>,) if the buffer of the one we&#8217;re not reading gets full, we deadlock.</p>
<p>The solution would be to read a little from each. This would work, except for the little problem that if we read from a stream that doesn&#8217;t have data, we&#8217;d block until it gets data. This is exactly like the situation we were trying to avoid. A deadlock will happen when the other stream&#8217;s buffer is full, so the child process will block on writing to it, while we are waiting to read from the <em>other</em> stream that has no data yet.</p>
<h3>Peek to the Rescue?</h3>
<p>The <code>Process</code> class exposes both <code>StandardOutput</code> or <code>StandardError</code> streams, which have a <code><a href="http://msdn.microsoft.com/en-us/library/system.io.streamreader.peek.aspx">Peek</a>()</code> function that returns the next character without removing it from the buffer. It returns -1 when we have no data to read, so we postpone reading until <code>Peek()</code> returns &gt; -1.</p>
<p>Albeit, this won&#8217;t work. As <a href="http://stackoverflow.com/questions/4557591/alternative-to-streamreader-peek-and-thread-interrupt">many</a> have <a href="http://zachsaw.blogspot.ca/2011/07/streamreaderpeek-can-block-another-net.html">pointed out</a>, <a href="http://jrwren.wrenfam.com/blog/2005/08/09/streamreaderpeek-can-block/">StreamReader.Peek can block!</a> Which is ironic, considering that one would typically use it to poll the stream.</p>
<p>It seems we have no more hope in the synchronous world. We have no getters to query the available data as in <code><a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.dataavailable.aspx">NetworkStream.DataAvailable</a></code> and length will throw an exception as it needs a seekable stream (which we haven&#8217;t). So we&#8217;re back to the Asynchronous world.</p>
<h2>The Solution: No Solution!</h2>
<p>I was almost sure I found an answer with direct access to the <code>StandardOutput</code> or <code>StandardError</code> streams. After all, these are just wrappers around the Win32 pipes. The async I/O in .Net is really a wrapper around the native Windows async infrastructure. So, in theory, we don&#8217;t need all the layers that <code>Process</code> and other class add on top of the raw interfaces. Asynchronous I/O in Windows works by passing an (typically manual-reset) event object and a callback function. All we really need is the event to get triggered. Lo and behold, we are also get a wait-handle in the <code>IAsyncResult</code> that <code>BeginRead</code> of <code>Stream</code> returns. So we could wait on it directly, as these are triggered by the FileSystem drivers, after issuing async reads like this:</p>
<pre class="brush:csharp">  var outAsyncRes = process.StandardOutput.BaseStream.BeginRead(outBuffer, 0, BUFFER_LEN, null, null);
  var errAsyncRes = process.StandardError.BaseStream.BeginRead(errBuffer, 0, BUFFER_LEN, null, null);
  var events = new[] { outAsyncRes.AsyncWaitHandle, errAsyncRes.AsyncWaitHandle };
  WaitHandle.WaitAny(events, waitTimeMs);</pre>
<p>Except, this wouldn&#8217;t work. There are two reasons why this doesn&#8217;t work, one blame goes to the OS and one to .Net.</p>
<h3>Async Event Not Triggered by OS</h3>
<p>The first issue is that Windows doesn&#8217;t always signal this even. You read that right. In fact, a comment in the FileStream code reads:</p>
<pre>                // Consider uncommenting this someday soon - the EventHandle 
                // in the Overlapped struct is really useless half of the
                // time today since the OS doesn't signal it. [...]</pre>
<p>True, <a href="http://msdn.microsoft.com/en-ca/library/windows/desktop/aa365603(v=vs.85).aspx">the state of the event object is not changed if the operation finishes before the function returns</a>.</p>
<h3>.Net Callback Interop via ThreadPool</h3>
<p>Because the event isn&#8217;t signaled in all cases, .Net needs to manually signal this event object when the Overlapped I/O callback is invoked. You&#8217;d think that would save the day. Albeit, the Overlapped I/O callback doesn&#8217;t call into managed code. The CLR handles such callbacks in a special way. In fact it knows about File I/O and .Net wrappers aren&#8217;t written in pure P/Invoke, but rather by support from the CLR as well as standard P/Invoke.</p>
<p>Because the system can&#8217;t invoke managed callbacks, the solution is for the CLR to do it itself. Of course this needs to be one in a responsive fashion, and without blocking all of CLR for each callback invocation  What better solution than to queue a task on the <code>ThreadPool</code> that invokes the .Net callback? This callback will signal the event object we got in the <code>IAsyncResult</code> and, if set, it&#8217;ll call our delegate that we could pass to the <code>BeginRead</code> call.</p>
<p>So we&#8217;re back 180 degrees to ThreadPool and the original dilemma.</p>
<h2>Conclusion</h2>
<p>The task at hand seemed simple enough. Indeed, even after 5 posts, I still feel the frustration of not finding a generic solution that is both scalable and abstract. We&#8217;ve tried simple synchronous I/O, then switched to async, only to find that our waits can&#8217;t be satisfied because they are serviced by the worker threads that we are using to wait for the reads to complete. This took us to a polling strategy, that, once again, failed because the classes we are working with do not allow us to poll without blocking. The OS could have saved the day but because we&#8217;re in the belly of .Net, we have to play with its rules and that meant the OS callbacks had to be serviced on the same worker threads we are blocking. The ThreadPool is another stubbornly designed process-wide object that doesn&#8217;t allow us to gracefully and, more importantly, thread-safely, query and modify.</p>
<p>This means that we either need to explicitly use Tasks and the <code>ProcessExecutor</code> class we designed in the <a href="http://blog.ashodnakashian.com/?p=2117">previous post</a> or we need to roll our own internal thread pool to service the waits.</p>
<p>It is very easy to overlook a cyclic dependency such as this, especially in the wake of abstraction and separation of responsibilities. The complex nature of things was the perfect setup to overlook the subtle assumptions and expectations of each part of the code: the process spawning, the I/O readers, <code>Parallel.ForEach</code> and ultimately, the generic and omnipresent, <code>ThreadPool</code>.</p>
<p>The only hope for solving similar problems is to first find them. By incorrectly assuming (as I did) that any thread-safe function can be wrapped in <code>Parallel.ForEach</code>, and patting oneself for the marvels and simplicity of modern programming languages and for being proud of our silently-failing achievement, we only miss the opportunity to do so. By testing our code and verifying our assumptions, with skepticism and cynicism, rather than confidence and pride, do we stand a chance at finding out the sad truth, at least on the (hopefully) rare cases that we fail. Or abstraction fails, at any rate.</p>
<p>I can only wonder with a grin about other similar cases in the wild and how they are running slower than their brain-dead, one-at-a-time versions.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.ashodnakashian.com%2F2013%2F04%2Fasync-io-and-threadpool-deadlock-part-5%2F&amp;title=Async%20I%2FO%20and%20ThreadPool%20Deadlock%20%28Part%205%29" id="wpa2a_6"><img src="http://blog.ashodnakashian.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=RyNyh7HPFN4:K7QhEtzX7kI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=RyNyh7HPFN4:K7QhEtzX7kI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=RyNyh7HPFN4:K7QhEtzX7kI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=RyNyh7HPFN4:K7QhEtzX7kI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=RyNyh7HPFN4:K7QhEtzX7kI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=RyNyh7HPFN4:K7QhEtzX7kI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=RyNyh7HPFN4:K7QhEtzX7kI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=RyNyh7HPFN4:K7QhEtzX7kI:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=RyNyh7HPFN4:K7QhEtzX7kI:l6gmwiTKsz0"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=l6gmwiTKsz0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=RyNyh7HPFN4:K7QhEtzX7kI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ashodnakashian/zpMw/~4/RyNyh7HPFN4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-5/</feedburner:origLink></item>
		<item>
		<title>Against, Against FEMEN</title>
		<link>http://feedproxy.google.com/~r/ashodnakashian/zpMw/~3/KkgH0CvZuUs/</link>
		<comments>http://blog.ashodnakashian.com/2013/04/against-against-femen/#comments</comments>
		<pubDate>Mon, 08 Apr 2013 03:17:06 +0000</pubDate>
		<dc:creator>Ashod Nakashian</dc:creator>
				<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Politics]]></category>
		<category><![CDATA[Feminism]]></category>

		<guid isPermaLink="false">http://blog.ashodnakashian.com/?p=2188</guid>
		<description><![CDATA[Apparently there is an ongoing war between FEMEN, a feminist organization that protests topless, and a group calling themselves Muslim Women Against Femen, among others. What is of interest to me is the rhetoric and politics at play. FEMEN is not exactly known for taking the diplomatic road to getting their voice across. Whatever their <a href='http://blog.ashodnakashian.com/2013/04/against-against-femen/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>Apparently there is an ongoing war between <a href="http://femen.org/">FEMEN</a>, a feminist organization that <a href="http://www.guardian.co.uk/world/2013/mar/20/naked-female-warrior-femen-topless-protesters">protests topless</a>, and a group calling themselves <a href="http://www.facebook.com/MuslimWomenAgainstFemen">Muslim Women Against Femen</a>, among others.</p>
<p>What is of interest to me is the rhetoric and politics at play. FEMEN is not exactly known for taking the diplomatic road to getting their voice across. Whatever their methods, whether one agrees with them or not, or <a href="http://www.newstatesman.com/bim-adewunmi/2013/04/inconsistency-femens-imperialist-one-size-fits-all-attitude">whether they are effective</a>, considering that so far they got huge backlash and won controversy more than anything, the response is certainly interesting.</p>
<p>The row ignited when Amina Tyler, a 19-year-old FEMEN activist, posted topless pictures of herself on FEMEN-Tunesia&#8217;s Facebook page with &#8220;Fuck your morals&#8221; in English and &#8220;My body is my own, not anyone&#8217;s honor&#8221; in Arabic. A certain preacher called Adel Almi was <a href="http://www.kapitalis.com/societe/15111-tunisie-amina-doit-etre-lapidee-jusqu-a-la-mort-estime-un-predicateur-islamiste.html">quoted by Tunisian newspaper Kapitalis</a> that she deserves 80 to a 100 lashes according to the sharia law, but added that due to the gravity of her actions, which he believed may encourage other women to do the same and bring an &#8220;epidemic&#8221; and &#8220;catastrophes,&#8221; merits <a href="http://www.huffingtonpost.co.uk/2013/03/22/topless-tunisian-feminist-amina-stoning-death_n_2930611.html">death by stoning</a>.</p>
<p><a href="http://www.huffingtonpost.co.uk/2013/04/04/topless-jihad-day-femens-war-islam-underway-protestors-tunisian-embassies-amina-tyler-pictures_n_3014000.html?1365083327">FEMEN has reacted</a> by protesting, as any <del>feminist</del> human should do. A photo of a man apparently kicking a topless FEMEN member protesting in front of the Great Mosque of Paris was posted in <a href="http://www.guardian.co.uk/commentisfree/2013/apr/05/femen-topless-protest-gloriously-crude">a piece on The Guardian</a>&#8216;s <em>Comment is Free</em> section. <a href="http://vimeo.com/63345035">A video of that protest</a>, with the man in question, is available on Vimeo.</p>
<p>Muslim Women Against Femen has <a href="http://voiceofarevolutionary.com/2013/04/05/an-open-letter-to-femen/">responded with an open letter</a> with eight-point objections of Muslimahs (Muslim women) to FEMEN. In addition, a number of women (including a child) have posted their photos on Facebook holding slogans to the same effect and <a href="http://www.huffingtonpost.co.uk/2013/04/05/muslim-women-against-femen-facebook-topless-jihad-pictures-amina-tyler_n_3021495.html">interviews with supporters on The Huffington Post</a>.</p>
<p>What is amazing is that between the preacher, Muslim Women Against Femen, and the women with the slogans, not a single reference is made to the young woman responsible for the debate in the first place. Amina Tyler is missing from the picture and there is good reason to fear for her life.</p>
<p>The Muslimahs who took to themselves the right and initiation to defend their rights and religion, some of whom are self-identified feminists, apparently forgot to do Tyler even a lip-service to denounce any harm that could be inflicted on her. Instead, they took the opportunity to first generalize and speak for all &#8220;Muslim women, women of colour and women from the Global South,&#8221; as if appointed spokespersons. Second, the opportunity to lash at &#8220;racist, imperialist, capitalist, white-supremacist, colonialists&#8221; was not missed, never mind that they are irrelevant.</p>
<p>Some of the slogans in the self-photos read &#8220;Do I look oppressed?&#8221; and a child of perhaps five held one that read &#8220;Shame on &#8216;FEMEN&#8217; Hijab is my right!&#8221; I do not see anyone taking anyone&#8217;s rights from them, if anything the rights of Amina are the ones at risk. Least of all the rights of a child, which, I should add, beyond their welfare, health and education they can barely demand any rights that adults don&#8217;t give them. Which raises the question of who, if not her parents, gave her the &#8220;right&#8221; to wear a hijab when she clearly is in no position to choose to wear one anymore than the blue-jeans that she has on. Besides, if these women are not oppressed, they need not answer to the calling. (Although I do wonder if that will remain to be the case if and when they decide to change their outfit.)</p>
<p>The open-letter doesn&#8217;t offer any more wisdom from the thirteen or so university students who wrote it. Rife with ignorant accusations, misguided rhetoric, contradictions and ad-hominem attack on the protesters. If they are to be believed, &#8220;FEMEN is a colonial, racist rubbish disguised as “women’s liberation”,&#8221; and &#8220;rubbing shoulders with far-right, racist and Islamophobic groups is just ANTI-FEMINIST beyond bounds&#8221; and &#8220;EXTREMELY DANGEROUS.&#8221; And members of FEMEN &#8220;don’t really care about violence and harm being inflicted upon women, you only care about that when it is perpetrated by brown men with long beards who pray five times a day.&#8221; Which is quite interesting considering that the group had focused most of its activity to protest against &#8220;sex tourists, religious institutions, international marriage agencies, sexism and other social, national and international topics.&#8221; In fact, had the authors check their facts they would have run into FEMEN&#8217;s <a href="http://www.myspace.com/femenukraine">four-point goals on their MySpace page</a> explicitly targets &#8220;Ukrainian women&#8221; and &#8220;Ukraine&#8221; explicitly. Not to mention that if anything Ukraine was a victim of -Russian- colonialism. (But I guess all &#8220;white&#8221; people are &#8220;racist&#8221; and &#8220;colonialist.&#8221;)</p>
<p>Completely oblivious to the irony that it was a Muslim (male) preacher who called for the lashing and stoning of Amina Tyler, the authors declare &#8220;we don’t have to conform to your customs of protest to emancipate ourselves. Our religion does that for us already, thank you very much.&#8221;</p>
<p>In a particularly off-topic and a below-the-belt swing, the epistle writers pulled a punch on the physique of the topless protesters saying that &#8220;not all of us are white, skinny, physically non-disabled [sic] and willing to whip off our tops merely for press attention.&#8221; Perhaps alluding to both being white and skinny as undesirable attributes in women (by who?). To add insult to injury, they advised them to &#8220;check yourselves before you go into the streets again.&#8221;</p>
<p>Perhaps of the more salient remark is that the authors &#8220;understand that it’s really hard for a lot of you white colonial &#8216;feminists&#8217; to believe, but- SHOCKER! – Muslim women and women of colour can come with their own autonomy, and fight back as well!&#8221; The takeaway seems to be that while encouraging Muslim women to protest against oppression is &#8220;racist,&#8221; to say &#8220;white colonial &#8216;feminists&#8217;&#8221; is not. (Again, never mind that Islam is not a race, but white is.)</p>
<p>They advise the protesters to &#8220;Take aim at male supremacy, not Islam.&#8221; Perhaps oblivious to the fact that some male supremacists are also Muslim. They conclude the letter with the banner &#8220;SMASH THE WHITE SUPREMACIST CAPITALIST PATRIARCHY! POWER TO THE MUSLIMAHS!&#8221;</p>
<p><strong>One has to wonder, what has colonialism and racism anything to do with defending the rights of a woman to post her own topless photos online without getting stoned to death?</strong></p>
<p>One could give them the benefit of doubt and assume they simply didn&#8217;t understand what the issue was, had these women not been from Birmingham and other &#8220;western,&#8221; &#8220;colonial,&#8221; &#8220;capitalist&#8221; and &#8220;imperial&#8221; cities, instead of the &#8220;Global South&#8221; and the middle-east. Not only did they fail to address the subject matter, that of a teenage woman getting death threats for no other reason that posting her own photos online, but they muddled the &#8220;messed up world&#8221; that &#8220;we live in&#8221; (as they called it) even further. <strong>Silence in the face of injustice and oppression is a form of injustice and oppression.</strong> Do they really believe Amina deserves to be stoned to death? That she is a &#8220;white colonial racist&#8221; herself to be fought? Or is anyone who doesn&#8217;t agree with their ultra-conservative views is an enemy to be chased away?</p>
<p>Muslim Women Against Femen are not oppressed, but they wouldn&#8217;t lift a finger to support a sister under death treat. They wouldn&#8217;t recognize her right to control her body and her outfit. They wouldn&#8217;t even speak out against the preacher who is openly encouraging others to take matters into their own hands and apply the harsh law of lashing, nay, stoning her. Instead, they took to grinding the ax of &#8220;white colonialism.&#8221; Like the preacher, they feel threatened, and fear a &#8220;epidemic&#8221; of sorts.</p>
<p>&#8220;Nudity DOES NOT liberate me and I DO NOT need saving&#8221; read on of the slogans. Perhaps, but you aren&#8217;t implying that Amina doesn&#8217;t need or deserve saving either, are you?</p>
<p><span style="font-size: 13px;"><em>What feminist ignores the need of another woman under attack by male preachers calling for her stoning?</em> Apparently those who believe the protests of FEMEN is a &#8220;crusade.&#8221;</span></p>
<p>Meanwhile, a <a href="http://www.change.org/petitions/petitioning-tunisian-government-amina-must-be-safe">petition to prosecute</a> those who threatened Amina Tyler&#8217;s life has already collected more than 110,000 signatures. At least there are still some left who differentiate between agreeing <em>with</em> someone&#8217;s opinion and agreeing <em>to their right</em> of having an opinion.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.ashodnakashian.com%2F2013%2F04%2Fagainst-against-femen%2F&amp;title=Against%2C%20Against%20FEMEN" id="wpa2a_8"><img src="http://blog.ashodnakashian.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KkgH0CvZuUs:VfBkJKQj35o:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=KkgH0CvZuUs:VfBkJKQj35o:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KkgH0CvZuUs:VfBkJKQj35o:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KkgH0CvZuUs:VfBkJKQj35o:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=KkgH0CvZuUs:VfBkJKQj35o:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KkgH0CvZuUs:VfBkJKQj35o:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=KkgH0CvZuUs:VfBkJKQj35o:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KkgH0CvZuUs:VfBkJKQj35o:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KkgH0CvZuUs:VfBkJKQj35o:l6gmwiTKsz0"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=l6gmwiTKsz0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KkgH0CvZuUs:VfBkJKQj35o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ashodnakashian/zpMw/~4/KkgH0CvZuUs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.ashodnakashian.com/2013/04/against-against-femen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ashodnakashian.com/2013/04/against-against-femen/</feedburner:origLink></item>
		<item>
		<title>Async I/O and ThreadPool Deadlock (Part 4)</title>
		<link>http://feedproxy.google.com/~r/ashodnakashian/zpMw/~3/Q7sZi7ZYrgI/</link>
		<comments>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-4/#comments</comments>
		<pubDate>Fri, 05 Apr 2013 06:46:28 +0000</pubDate>
		<dc:creator>Ashod Nakashian</dc:creator>
				<category><![CDATA[Code Snippet]]></category>
		<category><![CDATA[From the Trenches]]></category>
		<category><![CDATA[Guides]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Deadlock]]></category>
		<category><![CDATA[Leaky Abstraction]]></category>
		<category><![CDATA[Parallelization]]></category>
		<category><![CDATA[Pipes]]></category>
		<category><![CDATA[Threading]]></category>
		<category><![CDATA[ThreadPool]]></category>
		<category><![CDATA[Win32]]></category>

		<guid isPermaLink="false">http://blog.ashodnakashian.com/?p=2117</guid>
		<description><![CDATA[In part 3 we found out that executing Process instances in Parallel.ForEach could starve ThreadPool and cause a deadlock. In this part, we&#8217;ll attempt at solving the problem. What we&#8217;d like to have is a function or class that executes and reads the outputs of an external process such that it could be used concurrently, <a href='http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-4/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://blog.ashodnakashian.com/?p=2111">In part 3</a> we found out that executing Process instances in <code>Parallel.ForEach</code> could starve <code>ThreadPool</code> and cause a deadlock. In this part, we&#8217;ll attempt at solving the problem.<br />
<br />
What we&#8217;d like to have is a function or class that executes and reads the outputs of an external process such that it could be used concurrently, in <code>Parallel.ForEach</code> or with <code>Tasks</code> without ill-effects or without the user taking special precautions to avoid these problems.</p>
<h3>A Solution</h3>
<p>A naïve solution is to make sure there is at least one thread available in the pool when blocking on the child process and its output. In other words, the number of threads in the pool must be larger than the <code>MaxDegreeOfParallelism</code> of the <code>ForEach</code> loop. This will only work when there are no other users of the <code>ThreadPool</code>, then we can control these two numbers to guarantee this inequality. Even then, we might potentially need a large number of threads in the pool. But the problem is inescapable as we can&#8217;t control the complete process at all times. To make matters worse, the API for changing the number of workers in the pool are non-atomic and will always have race conditions when changing these process-wide settings.</p>
<p>Broadly speaking, there are three solutions. The first is to replace <code>Parallel.ForEach</code> with something else. The second is to replace the Process class with our own, such that we have a more flexible design that avoid the wasting a thread to wait on the callback events. The third is to replace the <code>ThreadPool</code>. The last can be done by simply having a private pool for waiting on the callback events. That is, unless we can find a way to make the native Process work with <code>Parallel.ForEach</code> without worrying about this issue.</p>
<p>Of course the best solution would be for the <code>ThreadPool</code> to be smarter and increase the number of threads available. This is the case when we set our wait functions to wait indefinitely. But that takes way too long (in my case about 12 seconds) before the <code>ThreadPool</code> realizes that no progress is being made, and it still has some tasks schedules for execution. It (correctly) assumes that there might be some interdependency between the running-but-not-progressing threads and those tasks waiting for execution.</p>
<p>The third solution is overly complicated and I&#8217;d find very little reason to defend it. Thread pools are rather complicated beasts and unless we can reuse one, it&#8217;d be an overkill to develop one. The first two solution look promising, so let&#8217;s try them out.</p>
<h3>Replacing Parallel.ForEach</h3>
<p>Clearly the above workarounds aren&#8217;t bulletproof. We can easily end up in situations where we timeout, and so it&#8217;d be a <a href="http://en.wikipedia.org/wiki/Red_Queen_hypothesis">Red Queen&#8217;s Race</a>. A better solution is to avoid the root of the problem, namely, to avoid wasting <code>ThreadPool</code> threads to wait on the processes. This can be done if we could make the wait more efficient, by combining the waits of multiple processes together. In that case, it wouldn&#8217;t matter if we used a single <code>ThreadPool</code> thread, or a dedicated one.</p>
<p>To that end, we need to do two things. First, we need to convert the single function into an object that we can move around, because we&#8217;ll need to reference its locals directly. Second, we need to separate the wait from all the other setup code.</p>
<p>Here is a wrapper that is disposable, and wraps cleanly around Process.</p>
<pre class="brush:csharp">        public class ProcessExecutor : IDisposable
        {
            public ProcessExecutor(string name, string path)
            {
                _name = name;
                _path = path;
            }

            public void Dispose()
            {
                Close();
            }

            public string Name { get { return _name; } }
            public string StdOut { get { return _stdOut.ToString(); } }
            public string StdErr { get { return _stdErr.ToString(); } }

            // Returns the internal process. Used for getting exit code and other advanced usage.
            // May be proxied by getters. But for now let's trust the consumer.
            public Process Processs { get { return _process; } }

            public bool Run(string args)
            {
                // Make sure we are don't have any old baggage.
                Close();

                // Fresh start.
                _stdOut.Clear();
                _stdErr.Clear();
                _stdOutEvent = new ManualResetEvent(false);
                _stdErrEvent = new ManualResetEvent(false);

                _process = new Process();
                _process.StartInfo = new ProcessStartInfo(_path)
                {
                    Arguments = args,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    ErrorDialog = false,
                    CreateNoWindow = true,
                    WorkingDirectory = Path.GetDirectoryName(_path)
                };

                _process.OutputDataReceived += (sender, e) =&gt;
                {
                    _stdOut.AppendLine(e.Data);
                    if (e.Data == null)
                    {
                        var evt = _stdOutEvent;
                        if (evt != null)
                        {
                            lock (evt)
                            {
                                evt.Set();
                            }
                        }
                    }
                };
                _process.ErrorDataReceived += (sender, e) =&gt;
                {
                    _stdErr.AppendLine(e.Data);
                    if (e.Data == null)
                    {
                        var evt = _stdErrEvent;
                        lock (evt)
                        {
                            evt.Set();
                        }
                    }
                };

                _sw = Stopwatch.StartNew();
                _process.Start();
                _process.BeginOutputReadLine();
                _process.BeginErrorReadLine();
                _process.Refresh();
                return true;
            }

            public void Cancel()
            {
                var proc = _process;
                _process = null;
                if (proc != null)
                {
                    // Invalidate cached data to requery.
                    proc.Refresh();

                    // Cancel all pending IO ops.
                    proc.CancelErrorRead();
                    proc.CancelOutputRead();

                    Kill();
                }

                var outEvent = _stdOutEvent;
                _stdOutEvent = null;
                if (outEvent != null)
                {
                    lock (outEvent)
                    {
                        outEvent.Close();
                        outEvent.Dispose();
                    }
                }

                var errEvent = _stdErrEvent;
                _stdErrEvent = null;
                if (errEvent != null)
                {
                    lock (errEvent)
                    {
                        errEvent.Close();
                        errEvent.Dispose();
                    }
                }
            }

            public void Wait()
            {
                Wait(-1);
            }

            public bool Wait(int timeoutMs)
            {
                try
                {
                    if (timeoutMs &lt; 0)
                    {
                        // Wait for process and all I/O to finish.
                        _process.WaitForExit();
                        return true;
                    }

                    // Timed waiting. We need to wait for I/O ourselves.
                    if (!_process.WaitForExit(timeoutMs))
                    {
                        Kill();
                    }

                    // Wait for the I/O to finish.
                    var waitMs = (int)(timeoutMs - _sw.ElapsedMilliseconds);
                    waitMs = Math.Max(waitMs, 10);
                    _stdOutEvent.WaitOne(waitMs);

                    waitMs = (int)(timeoutMs - _sw.ElapsedMilliseconds);
                    waitMs = Math.Max(waitMs, 10);
                    return _stdErrEvent.WaitOne(waitMs);
                }
                finally
                {
                    // Cleanup.
                    Cancel();
                }
            }

            private void Close()
            {
                Cancel();
                var proc = _process;
                _process = null;
                if (proc != null)
                {
                    // Dispose in all cases.
                    proc.Close();
                    proc.Dispose();
                }
            }

            private void Kill()
            {
                try
                {
                    // We need to do this in case of a non-UI proc
                    // or one to be forced to cancel.
                    var proc = _process;
                    if (proc != null &amp;&amp; !proc.HasExited)
                    {
                        proc.Kill();
                    }
                }
                catch
                {
                    // Kill will throw when/if the process has already exited.
                }
            }

            private readonly string _name;
            private readonly string _path;
            private readonly StringBuilder _stdOut = new StringBuilder(4 * 1024);
            private readonly StringBuilder _stdErr = new StringBuilder(4 * 1024);

            private ManualResetEvent _stdOutEvent;
            private ManualResetEvent _stdErrEvent;
            private Process _process;
            private Stopwatch _sw;
        }</pre>
<p>Converting this to use Tasks is left as an exercise to the reader.</p>
<p>Now, we can use this in a different way.</p>
<pre class="brush:csharp">        public static void Run(List&lt;KeyValuePair&lt;string, string&gt;&gt; pathArgs, int timeout)
        {
            var cts = new CancellationTokenSource();
            var allProcesses = Task.Factory.StartNew(() =&gt;
            {
                var tasks = pathArgs.Select(pair =&gt; Task.Factory.StartNew(() =&gt;
                {
                    string name = Path.GetFileNameWithoutExtension(pair.Key);
                    var exec = new ProcessExecutor(name, pair.Key);
                    exec.Run(pair.Value);
                    cts.Token.Register(exec.Cancel);
                    return exec;
                })).ToArray();

                // Wait for individual tasks to finish.
                foreach (var task in tasks)
                {
                    if (task != null)
                    {
                        task.Result.Wait(timeout);
                        task.Result.Cancel();
                        task.Result.Dispose();
                        task.Dispose();
                    }
                }
            });

            // Cancel, if we timed out.
            allProcesses.Wait(timeout);
            cts.Cancel();
        }</pre>
<p>This time, we fire each process executor in a separate thread (also a worker on the <code>ThreadPool</code>,) but we wait in a single thread. The worker threads will run, and they will have their async reads queued, which will run once the exec.Run() functions return, and free that thread, at which point the async reads will execute.</p>
<p>Notice that we are creating the new tasks in a worker thread. This is so that we can limit the wait on <em>all</em> of them (although we&#8217;d need to have a timeout that depends on their number. But for illustration purpose the above code is sufficient. Now we have the luxury of waiting on all of them in a single Wait call and we can also cancel all of them using the <code>CancellationTokenSource</code>.</p>
<p>The above code is typically finishing in about 5-6 seconds (and as low as 4006ms) for 500 child processes on 12 cores to echo a short string and exit.</p>
<p>One thing to keep in mind when using this code is that if we use <code>ProcessExecutor</code> in another class, as a member, that class should also separate and expose the Run and Wait functions separately. That is, if it simply calls Run followed by Wait in the same function, then they will both execute on the same thread, which will result in the same problem if a number of them get executed on the <code>ThreadPool</code>, as we did. So the abstraction will leak again!</p>
<p>In addition, this puts the onus in the hands of the consumer. Our <code>ProcessExecutor</code> class is not bulletproof on its own.</p>
<p><strong><em>In the next and final part we&#8217;ll go back to the <code>Process</code> class to try and avoid the deadlock issue without assuming a specific usage pattern.</em></strong></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.ashodnakashian.com%2F2013%2F04%2Fasync-io-and-threadpool-deadlock-part-4%2F&amp;title=Async%20I%2FO%20and%20ThreadPool%20Deadlock%20%28Part%204%29" id="wpa2a_10"><img src="http://blog.ashodnakashian.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=Q7sZi7ZYrgI:nIqc37lEk64:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=Q7sZi7ZYrgI:nIqc37lEk64:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=Q7sZi7ZYrgI:nIqc37lEk64:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=Q7sZi7ZYrgI:nIqc37lEk64:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=Q7sZi7ZYrgI:nIqc37lEk64:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=Q7sZi7ZYrgI:nIqc37lEk64:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=Q7sZi7ZYrgI:nIqc37lEk64:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=Q7sZi7ZYrgI:nIqc37lEk64:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=Q7sZi7ZYrgI:nIqc37lEk64:l6gmwiTKsz0"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=l6gmwiTKsz0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=Q7sZi7ZYrgI:nIqc37lEk64:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ashodnakashian/zpMw/~4/Q7sZi7ZYrgI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-4/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-4/</feedburner:origLink></item>
		<item>
		<title>Async I/O and ThreadPool Deadlock (Part 3)</title>
		<link>http://feedproxy.google.com/~r/ashodnakashian/zpMw/~3/CkuTk85l0SM/</link>
		<comments>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-3/#comments</comments>
		<pubDate>Thu, 04 Apr 2013 06:46:01 +0000</pubDate>
		<dc:creator>Ashod Nakashian</dc:creator>
				<category><![CDATA[Code Snippet]]></category>
		<category><![CDATA[From the Trenches]]></category>
		<category><![CDATA[Guides]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Deadlock]]></category>
		<category><![CDATA[Leaky Abstraction]]></category>
		<category><![CDATA[Parallelization]]></category>
		<category><![CDATA[Pipes]]></category>
		<category><![CDATA[Threading]]></category>
		<category><![CDATA[ThreadPool]]></category>
		<category><![CDATA[Win32]]></category>

		<guid isPermaLink="false">http://blog.ashodnakashian.com/?p=2111</guid>
		<description><![CDATA[In part 2 we discovered that by executing Process instances in Parallel.ForEach we are getting reduced performance and our waits are timing out. In this part we&#8217;ll dive deep into the problem and find out what is going on. Deadlock Clearly the problem has to do with the Process class and/or with spawning processes in <a href='http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-3/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://blog.ashodnakashian.com/?p=2110">In part 2</a> we discovered that by executing Process instances in <code>Parallel.ForEach</code> we are getting <em>reduced</em> performance and our waits are timing out. In this part we&#8217;ll dive deep into the problem and find out what is going on.</p>

<h3>Deadlock</h3>
<p>Clearly the problem has to do with the <code>Process</code> class and/or with spawning processes in general. Looking more carefully, we notice that besides the spawned process we also have two asynchronous reads. We have intentionally requested these to be executed on separate threads. But that shouldn&#8217;t be a problem, unless we have misused the async API.</p>
<p>It is reasonable to suspect that the approach used to do the async reading is at fault. This is where I ventured to look at the <code>Process</code> class code. After all, it&#8217;s a wrapper on Win32 API, and it might make assumptions that I was ignoring or contradicting. Regrettably, that didn&#8217;t help to figure out what was going on, except for initiating me to write the <a href="http://blog.ashodnakashian.com/?p=2036">said previous post</a>.</p>
<p>Looking at the <code>BeginOutputReadLine()</code> function, we see it creating an <code>AsyncStreamReader</code>, which is internal to the .Net Framework and then calls <code>BeginReadLine()</code>, which presumably is where the async action happens.</p>
<pre class="brush:csharp">        [System.Runtime.InteropServices.ComVisible(false)] 
        public void BeginOutputReadLine() {

            if(outputStreamReadMode == StreamReadMode.undefined) { 
                outputStreamReadMode = StreamReadMode.asyncMode;
            } 
            else if (outputStreamReadMode != StreamReadMode.asyncMode) {
                throw new InvalidOperationException(SR.GetString(SR.CantMixSyncAsyncOperation));
            }

            if (pendingOutputRead)
                throw new InvalidOperationException(SR.GetString(SR.PendingAsyncOperation)); 

            pendingOutputRead = true;
            // We can't detect if there's a pending sychronous read, tream also doesn't. 
            if (output == null) {
                if (standardOutput == null) {
                    throw new InvalidOperationException(SR.GetString(SR.CantGetStandardOut));
                } 

                Stream s = standardOutput.BaseStream; 
                output = new AsyncStreamReader(this, s, new UserCallBack(this.OutputReadNotifyUser), standardOutput.CurrentEncoding); 
            }
            output.BeginReadLine(); 
        }</pre>
<p>Within the <code>AsyncStreamReader.BeginReadLine()</code> we see the familiar asynchronous read on Stream using <a href="http://msdn.microsoft.com/en-CA/library/system.io.stream.beginread.aspx"><code>Stream.BeginRead()</code></a>.</p>
<pre class="brush:csharp">        // User calls BeginRead to start the asynchronous read
        internal void BeginReadLine() { 
            if( cancelOperation) {
                cancelOperation = false; 
            } 

            if( sb == null ) { 
                sb = new StringBuilder(DefaultBufferSize);
                stream.BeginRead(byteBuffer, 0 , byteBuffer.Length,  new AsyncCallback(ReadBuffer), null);
            }
            else { 
                FlushMessageQueue();
            } 
        }</pre>
<p>Unfortunately, I had incorrectly assumed that this async wait was executed on one of the I/O Completion Port threads of the <code>ThreadPool</code>. It seems that this is not the case, as <a href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getavailablethreads.aspx"><code>ThreadPool.GetAvailableThreads()</code></a> always returned the same number for <em>completionPortThreads</em> (incidentally, <em>workerThreads</em> value didn&#8217;t change much as well, but I didn&#8217;t notice that at first).</p>
<p>A breakthrough came when I started changing the maximum parallelism (i.e. maximum thread count) of <code>Parallel.ForEach</code>.</p>
<pre class="brush:csharp">        public static void ExecAll(List&lt;KeyValuePair&lt;string, string&gt;&gt; pathArgs, int timeout, int maxThreads)
        {
            Parallel.ForEach(pathArgs, new ParallelOptions { MaxDegreeOfParallelism = maxThreads },
                             arg =&gt; Task.Factory.StartNew(() =&gt; DoJob(arg.Value.Split(' '))).Wait() );
        }</pre>
<p>I thought I should increase the maximum number of threads to resolve the issue. Indeed, for certain values of MaxDegreeOfParallelism, I could never reproduce the problem (all processes finished very swiftly, and no timeouts). For everything else, the problem was reproducible most of the time. Nine out of ten I&#8217;d get timeouts. However, and to my surprise, the problem went away when I <em>reduced</em> MaxDegreeOfParallelism!</p>
<p>The magic number was 12. Yes, the number of cores at disposal on my dev machine. If we limit the number of concurrent <code>ForEach</code> executions to <em>less</em> than 12, everything finishes swiftly, otherwise, we get timeouts and finishing <code>ExecAll()</code> takes a long time. In fact, with maxThreads=11, 500 process executions finish under 8500ms, which is very commendable. However, with maxThreads=12, every 12 process wait until they timeout, which would take several minutes to finish all 500.</p>
<p>With this information, I tried increasing the <code>ThreadPool</code> limit of threads using <a href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.setmaxthreads.aspx"><code>ThreadPool.SetMaxThreads()</code></a>. But it turns out the defaults are 1023 worker threads and 1000 for I/O Completion Port threads, as reported by <code><a href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads.aspx">ThreadPool.GetMaxThreads()</a></code>. I was assuming that if the available thread count was lower than the required, the <code>ThreadPool</code> would simply create new threads until it reached the maximum configured value.</p>
<div id="attachment_2145" class="wp-caption alignright" style="width: 310px"><a class="highslide img_1" href="http://blog.ashodnakashian.com/wp-content/uploads/2013/03/ThreadPool-Deadlock.png" onclick="return hs.expand(this)"><img class="size-medium wp-image-2145" title="Diagram showing deadlock (created by www.gliffy.com)" alt="ThreadPool-Deadlock" src="http://blog.ashodnakashian.com/wp-content/uploads/2013/03/ThreadPool-Deadlock-300x177.png" width="300" height="177" /></a><p class="wp-caption-text">Diagram showing deadlock (created by www.gliffy.com)</p></div>
<h2>Putting It All Together</h2>
<p>The assumption that <code>Parallel.ForEach</code> executes its body on the <code>ThreadPool</code>, assuming said body is a black-box is clearly flawed. In our case the body is initiating asynchronous I/O which needs their own threads. Apparently, these do not come from the I/O thread pool but the worker thread pool. In addition, the number of threads in this pool is initially set to that of the available number of cores on the target machine. Even worse, it will resist creating new threads until absolutely necessary. Unfortunately, in our case it&#8217;s too late, as our waits are timing out. What I left until this point (both for dramatic effect and to leave the solution to you, the reader, to find out) is that the timeouts were happening on the <code>StandardOutput</code> and <code>StandardError</code> streams. That is, even though the child processes had exited a long time ago, we were still waiting to read their output.</p>
<p>Let me spell it out, if it&#8217;s not obvious: Each call to spawn and wait for a child process is executed on a <code>ThreadPool</code> worker thread, and is using it exclusively until the waits return. The async stream reads on <code>StandardOutput</code> and <code>StandardError</code> need to run on <em>some</em> thread. Since they are apparently queued to run on a <code>ThreadPool</code> thread, they will starve if we use all of the available threads in the pool to wait on them to finish. Thereby timing out on the read waits (because we have a deadlock).</p>
<p>This is a case of Leaky Abstraction, as our black box of a &#8220;execute on ThreadPool&#8221; failed miserably when the code executed itself depended on the <code>ThreadPool</code>. Specifically, when we had used all available threads in the pool, we left none for <em>our</em> code that depends on the <code>ThreadPool</code> to use. We shot ourselves in the proverbial foot. Our abstraction failed.</p>
<p><strong><em>In the <a href="http://blog.ashodnakashian.com/?p=2117">next part</a> we&#8217;ll attempt to solve the problem.</em></strong></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.ashodnakashian.com%2F2013%2F04%2Fasync-io-and-threadpool-deadlock-part-3%2F&amp;title=Async%20I%2FO%20and%20ThreadPool%20Deadlock%20%28Part%203%29" id="wpa2a_12"><img src="http://blog.ashodnakashian.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=CkuTk85l0SM:X1uxA3Prnzg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=CkuTk85l0SM:X1uxA3Prnzg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=CkuTk85l0SM:X1uxA3Prnzg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=CkuTk85l0SM:X1uxA3Prnzg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=CkuTk85l0SM:X1uxA3Prnzg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=CkuTk85l0SM:X1uxA3Prnzg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=CkuTk85l0SM:X1uxA3Prnzg:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=CkuTk85l0SM:X1uxA3Prnzg:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=CkuTk85l0SM:X1uxA3Prnzg:l6gmwiTKsz0"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=l6gmwiTKsz0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=CkuTk85l0SM:X1uxA3Prnzg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ashodnakashian/zpMw/~4/CkuTk85l0SM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-3/</feedburner:origLink></item>
		<item>
		<title>Async I/O and ThreadPool Deadlock (Part 2)</title>
		<link>http://feedproxy.google.com/~r/ashodnakashian/zpMw/~3/KMLP9ZgZ9vk/</link>
		<comments>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-2/#comments</comments>
		<pubDate>Wed, 03 Apr 2013 06:46:24 +0000</pubDate>
		<dc:creator>Ashod Nakashian</dc:creator>
				<category><![CDATA[Code Snippet]]></category>
		<category><![CDATA[From the Trenches]]></category>
		<category><![CDATA[Guides]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Deadlock]]></category>
		<category><![CDATA[Leaky Abstraction]]></category>
		<category><![CDATA[Parallelization]]></category>
		<category><![CDATA[Pipes]]></category>
		<category><![CDATA[Threading]]></category>
		<category><![CDATA[ThreadPool]]></category>
		<category><![CDATA[Win32]]></category>

		<guid isPermaLink="false">http://blog.ashodnakashian.com/?p=2110</guid>
		<description><![CDATA[In part 1 we discovered a deadlock in the synchronous approach to reading the output of Process and we solved it using asynchronous reads. Today we&#8217;ll parallelize the execution in an attempt to maximize efficiency and concurrency. Parallel Execution Now, let&#8217;s complicate our lives with some concurrency, shall we? If we are to spawn many <a href='http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-2/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://blog.ashodnakashian.com/?p=2062">In part 1</a> we discovered a deadlock in the synchronous approach to reading the output of Process and we solved it using asynchronous reads. Today we&#8217;ll parallelize the execution in an attempt to maximize efficiency and concurrency.</p>

<h2>Parallel Execution</h2>
<p>Now, let&#8217;s complicate our lives with some concurrency, shall we?</p>
<p>If we are to spawn many processes, we could (and should) utilize all the cores at our disposal. Thanks to <a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.for.aspx"><code>Parallel.For</code></a> and <a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx"><code>Parallel.ForEach</code></a> this task is made much simpler than otherwise.</p>
<pre class="brush:csharp">        public static void ExecAll(List&lt;KeyValuePair&lt;string, string&gt;&gt; pathArgs, int timeout)
        {
            Parallel.ForEach(pathArgs, arg =&gt; ExecWithAsyncTasks(arg.Key, arg.Value, timeout));
        }</pre>
<p>Things couldn&#8217;t be any simpler! We pass a list of executable paths and their arguments as <code>KeyValuePair</code> and a timeout in milliseconds. Except, this won&#8217;t work&#8230; at least not always.</p>
<p>First, let&#8217;s discuss <em>how</em> it will not work, then let&#8217;s understand the <em>why</em> before we attempt to fix it.</p>
<h3>When Abstraction Backfires</h3>
<p>The above code works like a charm in many cases. When it doesn&#8217;t, a number of waits timeout. This is unacceptable as we wouldn&#8217;t know if we got all the output or part of it, unless we get a clean exit with no timeouts. I first noticed this issue in a completely different way. I was looking at the <del>task manager</del> <a href="http://technet.microsoft.com/en-ca/sysinternals/bb896653.aspx">Process Explorer</a> (if not using it, start now and I promise not to tell anyone,) to see how amazingly faster things are with that single <code>ForEach</code> line. I was expecting to see a dozen or so (on a 12-core machine) child processes spawning and vanishing in quick succession. Instead, and to my chagrin, I saw most of the time just one child! <em>One</em>!</p>
<p>And after many trials and head-scratching and reading, it became clear that the waits were timing out, even though clearly the children had finished and exited. Indeed, because typically a process would run in much less time than the timeout, it was now <em>slower</em> with the parallelized code than with the sequential version. This wasn&#8217;t obvious at first, and reasonably I suspected some children were taking too long, or they had too much to write to the output pipes that could be deadlocking (which wasn&#8217;t unfamiliar to me).</p>
<h3>Testbed</h3>
<p>To troubleshoot something as complex as this, one should start with clean test-case, with minimum number of variables. This calls for a dummy child that would do exactly as I told it, so that I could simulate different scenarios. One such scenario would be not to spawn any children at all, and just test the <code>Parallel.ForEach</code> with some in-proc task (i.e. just a local function that does similar work to that of a child).</p>
<pre class="brush:csharp">using System;
using System.Threading;

namespace Child
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length &lt; 2 || args.Length % 2 != 0)
            {
                Console.WriteLine("Usage: [echo|fill|sleep|return] ");
                return;
            }

            DoJob(args);
        }

        private static void DoJob(string[] args)
        {
            for (int argIdx = 0; argIdx &lt; args.Length; argIdx += 2)
            {
                switch (args[argIdx].ToLowerInvariant())
                {
                    case "echo":
                        Console.WriteLine(args[argIdx + 1]);
                        break;

                    case "fill":
                        var rd = new Random();
                        int bytes = int.Parse(args[argIdx + 1]);
                        while (bytes-- &gt; 0)
                        {
                            // Generate a random string as long as the .
                            Console.Write(rd.Next('a', 'z'));
                        }
                        break;

                    case "sleep":
                        Thread.Sleep(int.Parse(args[argIdx + 1]));
                        break;

                    case "return":
                        Environment.ExitCode = int.Parse(args[argIdx + 1]);
                        break;

                    default:
                        Console.WriteLine("Unknown command [" + args[argIdx] + "]. Skipping.");
                        break;
                }
            }
        }
    }
}</pre>
<p>Now we can give the child process commands to change its behavior, from dumping data to its output to sleeping to returning immediately.</p>
<p>Once the problem is reproduced, we can narrow it down to pin-point the source. Running the exact same command in the same process (i. e. without spawning another process) results in no problems at all. Calling <code>DoJob</code> 500 times directly in <code>Parallel.ForEach</code> finishes in under 500ms (often under 450ms). So we can be sure Parallel.ForEach is working fine.</p>
<pre class="brush:csharp">        public static void ExecAll(List&lt;KeyValuePair&lt;string, string&gt;&gt; pathArgs, int timeout)
        {
            Parallel.ForEach(pathArgs, arg =&gt; Task.Factory.StartNew(() =&gt; DoJob(arg.Value.Split(' '))).Wait() );
        }</pre>
<p>Even executing as a new task (within the <code>Parallel.ForEach</code>) doesn&#8217;t result in any noticeable different in time. The reason for this good performance when running the jobs in new tasks is probably because the <code>ThreadPool</code> scheduler does fetch the task to execute immediately when we call <code>Wait()</code> and executes it. That is, because both the <code>Task.Factory.StartNew()</code> call as well as the <code>DoJob()</code> call are executed ultimately on the <code>ThreadPool</code>, and because Task is designed specifically to utilize it, when we call <code>Wait()</code> on the task, it knows that it should schedule the next job in the queue, which in this case is the job of the task on which we executed the Wait! Since the caller of <code>Wait()</code> happens to be running on the <code>ThreadPool</code>, it simply executes it instead of scheduling it on a different thread and blocking. Dumping the <code>Thread.CurrentThread.ManagedThreadId</code> from before the <code>Task.Factory.StartNew()</code> call and from within <code>DoJob</code> shows that indeed both are executed in the same thread. The overhead of creating and scheduling a Task is negligible, so we don&#8217;t see much of a change in time over 500 executions.</p>
<p>All this is great and comforting, but still doesn&#8217;t help us resolve the problem at hand: <em>why aren&#8217;t our processes spawned and executed at the highest possible efficiency? And why are they timing out?</em></p>
<p><strong><em>In the <a href="http://blog.ashodnakashian.com/?p=2111">next part</a> we&#8217;ll dive deep into the problem and find out what is going on.</em></strong></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.ashodnakashian.com%2F2013%2F04%2Fasync-io-and-threadpool-deadlock-part-2%2F&amp;title=Async%20I%2FO%20and%20ThreadPool%20Deadlock%20%28Part%202%29" id="wpa2a_14"><img src="http://blog.ashodnakashian.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KMLP9ZgZ9vk:i5QH423J3Y8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=KMLP9ZgZ9vk:i5QH423J3Y8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KMLP9ZgZ9vk:i5QH423J3Y8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KMLP9ZgZ9vk:i5QH423J3Y8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=KMLP9ZgZ9vk:i5QH423J3Y8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KMLP9ZgZ9vk:i5QH423J3Y8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=KMLP9ZgZ9vk:i5QH423J3Y8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KMLP9ZgZ9vk:i5QH423J3Y8:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KMLP9ZgZ9vk:i5QH423J3Y8:l6gmwiTKsz0"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=l6gmwiTKsz0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KMLP9ZgZ9vk:i5QH423J3Y8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ashodnakashian/zpMw/~4/KMLP9ZgZ9vk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-2/</feedburner:origLink></item>
		<item>
		<title>Async I/O and ThreadPool Deadlock (Part 1)</title>
		<link>http://feedproxy.google.com/~r/ashodnakashian/zpMw/~3/sb2YYsR1HIU/</link>
		<comments>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-1/#comments</comments>
		<pubDate>Tue, 02 Apr 2013 06:46:37 +0000</pubDate>
		<dc:creator>Ashod Nakashian</dc:creator>
				<category><![CDATA[Code Snippet]]></category>
		<category><![CDATA[From the Trenches]]></category>
		<category><![CDATA[Guides]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Deadlock]]></category>
		<category><![CDATA[Leaky Abstraction]]></category>
		<category><![CDATA[Parallelization]]></category>
		<category><![CDATA[Pipes]]></category>
		<category><![CDATA[Threading]]></category>
		<category><![CDATA[ThreadPool]]></category>
		<category><![CDATA[Win32]]></category>

		<guid isPermaLink="false">http://blog.ashodnakashian.com/?p=2062</guid>
		<description><![CDATA[I&#8217;ve mentioned in a past post that it was conceived while reading the source code for the System.Diagnostics.Process class. This post is about the reason that pushed me to read the source code in an attempt to fix the issue. It turned out that this was yet another case of Leaky Abstraction, which is a <a href='http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-1/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve <a href="http://blog.ashodnakashian.com/?p=2036">mentioned in a past post</a> that it was conceived while reading the source code for the <code>System.Diagnostics.Process</code> class. This post is about the reason that pushed me to read the source code in an attempt to fix the issue. It turned out that this was yet another case of <a href="http://blog.ashodnakashian.com/?p=416">Leaky</a> <a href="http://blog.ashodnakashian.com/?p=415">Abstraction</a>, which is a special interest of mine.<br />
<br />
As it turned out, this post ended being way too long (even for me). I don&#8217;t like installments, but I felt that it is something that is worth trying as the size was prohibitive for single-post consumption. As such, I&#8217;ve split it up on 5 parts, so that each part would be around a 1000 words or less. I&#8217;ll post one part a day.</p>
<p>To give you an idea of the scope and subject of what&#8217;s to come, here is a quick overview. In part 1 I&#8217;ll lay out the problem. We are trying to spawn processes, read their output and kill if they take too long. Our first attempt is to use simple synchronous I/O to read the output and discover a deadlock. We solve the deadlock using asynchronous I/O. In part 2 we parallelize the code and discover reduced performance and yet another deadlock. We create a testbed and set about to investigate the problem at depth. In part 3 we will find out the root cause and we&#8217;ll discuss the mechanics (how and why) we hit such a problem. In part 4 we&#8217;ll discuss solutions to the problem and develop a generic solutions (with code) to fix the problem. Finally, in part 5 we see whether or not a generic solution could work before we summarize and conclude.</p>
<p>Let&#8217;s begin at the very beginning. Suppose you want to execute some program (call it child), get all its output (and error) and, if it doesn&#8217;t exit within some time limit, kill it. Notice that there is no interaction and no input. This is how tests are executed in <a href="http://phalanger.codeplex.com/">Phalanger</a> using a test runner.</p>
<h2>Synchronous I/O</h2>
<p>The <code><a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx">Process</a></code> class has conveniently exposed the underlying <a href="http://msdn.microsoft.com/en-us/library/ms682499.aspx">pipes</a> to the child process using stream instances StandardOutput and StandardError. And, like many, we too might be tempted to simply call <code>StandardOutput.ReadToEnd()</code> and <code>StandardError.ReadToEnd()</code>. Albeit, that would work, until it doesn&#8217;t. As <a href="http://blogs.msdn.com/b/oldnewthing/archive/2011/07/07/10183884.aspx">Raymond Chen noted</a>, it&#8217;ll work as long as the data fits into the internal pipe buffer. The problem with this approach is that we are asking to read until we reach the end of the data, which will only happen for certainty when the child process we spawned exits. However, when the buffer of the pipe which the child writes its output to is full, the child has to wait until there is free space in the buffer to write to. But, you say, what if we always read and empty the buffer?</p>
<p>Good idea, except, we need to do that for both StandardOutput and StandardError <em>at the same time</em>. In the <code>StandardOutput.ReadToEnd()</code> call we read every byte coming in the buffer until the child process exits. While we have drained the <code>StandardOutput</code> buffer (so that the child process can&#8217;t be possibly blocked on that,) if it fills the <code><em>StandardError</em></code> buffer, which we aren&#8217;t reading yet, we will deadlock. The child won&#8217;t exit until it fully writes to the <code>StandardError</code> buffer (which is full because no one is reading it,) meanwhile, we are waiting for the process to exit so we can be sure we read to the end of the <code>StandardOutput</code> before we return (and start reading <code>StandardError</code>). The same problem exists for StandardOutput, if we first read StandardError, hence the need to drain both pipe buffers as they are fed, not one after the other.</p>
<h2>Async Reading</h2>
<p>The obvious (and only practical) solution is to read <em>both </em> pipes at the same time using separate threads. To that end, there are mainly two approaches. The pre-4.0 approach (async events), and the 4.5-and-up approach (tasks).</p>
<h3>Async Reading with Events</h3>
<p>The code is reasonably straight forward as it uses .Net events. We have two manual-reset events and two delegates that get called asynchronously when we read a line from each pipe. We get null data when we hit the end of file (i.e. when the process exits) for each of the two pipes.</p>
<pre class="brush:csharp">        public static string ExecWithAsyncEvents(string path, string args, int timeoutMs)
        {
            using (var outputWaitHandle = new ManualResetEvent(false))
            {
                using (var errorWaitHandle = new ManualResetEvent(false))
                {
                    using (var process = new Process())
                    {
                        process.StartInfo = new ProcessStartInfo(path);
                        process.StartInfo.Arguments = args;
                        process.StartInfo.UseShellExecute = false;
                        process.StartInfo.RedirectStandardOutput = true;
                        process.StartInfo.RedirectStandardError = true;
                        process.StartInfo.ErrorDialog = false;
                        process.StartInfo.CreateNoWindow = true;

                        var sb = new StringBuilder(1024);
                        process.OutputDataReceived += (sender, e) =&gt;
                        {
                            sb.AppendLine(e.Data);
                            if (e.Data == null)
                            {
                                outputWaitHandle.Set();
                            }
                        };
                        process.ErrorDataReceived += (sender, e) =&gt;
                        {
                            sb.AppendLine(e.Data);
                            if (e.Data == null)
                            {
                                errorWaitHandle.Set();
                            }
                        };

                        process.Start();
                        process.BeginOutputReadLine();
                        process.BeginErrorReadLine();

                        process.WaitForExit(timeoutMs);
                        outputWaitHandle.WaitOne(timeoutMs);
                        errorWaitHandle.WaitOne(timeoutMs);

                        process.CancelErrorRead();
                        process.CancelOutputRead();

                        return sb.ToString();
                    }
                }
            }
        }</pre>
<p>We certainly can improve on the above code (for example we should make the total wait limit &lt;= <code>timeoutMs</code>) but you get the point with this sample. Also, no error handling or killing the child process when it times out and doesn&#8217;t exit.</p>
<h3>Async Reading with Tasks</h3>
<p>A much more simplified and sanitized approach is to use the new <code>System.Threading.Tasks</code> namespace/framework to do all the heavy-lifting for us. As you can see, the code has been cut by half and it&#8217;s much more readable, but we need Framework 4.5 and newer for this to work (although my target is 4.0, but for comparison purposes I gave it a spin). The results are the same.</p>
<pre class="brush:csharp">        public static string ExecWithAsyncTasks(string path, string args, int timeout)
        {
            using (var process = new Process())
            {
                process.StartInfo = new ProcessStartInfo(path);
                process.StartInfo.Arguments = args;
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError = true;
                process.StartInfo.ErrorDialog = false;
                process.StartInfo.CreateNoWindow = true;

                var sb = new StringBuilder(1024);

                process.Start();
                var stdOutTask = process.StandardOutput.ReadToEndAsync();
                var stdErrTask = process.StandardError.ReadToEndAsync();

                process.WaitForExit(timeout);
                stdOutTask.Wait(timeout);
                stdErrTask.Wait(timeout);

                return sb.ToString();
            }
        }</pre>
<p>Again, a healthy doze of error-handling is in order, but for illustration purposes left out. A point worthy of mention is that we can&#8217;t assume we read the streams by the time the child exits. There is a race condition and we still need to wait for the I/O operations to finish before we can read the results.</p>
<p><strong><em>In the <a href="http://blog.ashodnakashian.com/?p=2110">next part</a> we&#8217;ll parallelize the execution in an attempt to maximize efficiency and concurrency.</em></strong></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.ashodnakashian.com%2F2013%2F04%2Fasync-io-and-threadpool-deadlock-part-1%2F&amp;title=Async%20I%2FO%20and%20ThreadPool%20Deadlock%20%28Part%201%29" id="wpa2a_16"><img src="http://blog.ashodnakashian.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=sb2YYsR1HIU:I97wNfyOx1w:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=sb2YYsR1HIU:I97wNfyOx1w:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=sb2YYsR1HIU:I97wNfyOx1w:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=sb2YYsR1HIU:I97wNfyOx1w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=sb2YYsR1HIU:I97wNfyOx1w:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=sb2YYsR1HIU:I97wNfyOx1w:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=sb2YYsR1HIU:I97wNfyOx1w:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=sb2YYsR1HIU:I97wNfyOx1w:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=sb2YYsR1HIU:I97wNfyOx1w:l6gmwiTKsz0"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=l6gmwiTKsz0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=sb2YYsR1HIU:I97wNfyOx1w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ashodnakashian/zpMw/~4/sb2YYsR1HIU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ashodnakashian.com/2013/04/async-io-and-threadpool-deadlock-part-1/</feedburner:origLink></item>
		<item>
		<title>Thread Abort and Critical Regions (in .Net)</title>
		<link>http://feedproxy.google.com/~r/ashodnakashian/zpMw/~3/KYMnCSAeqhg/</link>
		<comments>http://blog.ashodnakashian.com/2013/03/thread-abort-and-critical-regions-in-net/#comments</comments>
		<pubDate>Mon, 18 Mar 2013 01:41:29 +0000</pubDate>
		<dc:creator>Ashod Nakashian</dc:creator>
				<category><![CDATA[Best Practice]]></category>
		<category><![CDATA[Guides]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Async Exception]]></category>
		<category><![CDATA[Constrained Execution Region]]></category>
		<category><![CDATA[Exception Handling]]></category>
		<category><![CDATA[Thread Abort]]></category>

		<guid isPermaLink="false">http://blog.ashodnakashian.com/?p=2036</guid>
		<description><![CDATA[I don&#8217;t need to see the source code of an API to code against. In fact, I actively discourage against depending (even psychologically) on the inner details of an implementation. The contract should be sufficient. Of course I&#8217;m assuming a well-designed API with good (at least decent) documentation. But sometimes often reality is more complicated than an <a href='http://blog.ashodnakashian.com/2013/03/thread-abort-and-critical-regions-in-net/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>I don&#8217;t need to see the source code of an API to code against. In fact, I actively discourage against depending (even psychologically) on the inner details of an implementation. The contract should be sufficient. Of course I&#8217;m assuming a well-designed API with good (at least decent) documentation. But <del>sometimes</del> often reality is more complicated than an ideal world.</p>

<h2>Empty try{}</h2>
<p>While working with <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.process(v=vs.100).aspx"><code>System.Diagnostics.Process</code></a> in the context of <a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach(v=vs.100).aspx"><code>Parallel.ForEach</code></a> things became a bit too complicated. (I&#8217;ll leave the gory details to another post.) What prompted this post was a weird pattern that I noticed while browsing <a href="http://reflector.webtropy.com/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/fx/src/Services/Monitoring/system/Diagnosticts/Process@cs/1305376/Process@cs">Process.cs</a>, the source code for the <code>Process</code> class (to untangle said complicated scenario).</p>
<pre class="brush:csharp">RuntimeHelpers.PrepareConstrainedRegions();
try {} finally {
   retVal = NativeMethods.CreateProcessWithLogonW(
		   startInfo.UserName,
		   startInfo.Domain,
		   password,
		   logonFlags,
		   null,            // we don't need this since all the info is in commandLine
		   commandLine,
		   creationFlags,
		   environmentPtr,
		   workingDirectory,
		   startupInfo,        // pointer to STARTUPINFO
		   processInfo         // pointer to PROCESS_INFORMATION
	   );
   if (!retVal)
	  errorCode = Marshal.GetLastWin32Error();
   if ( processInfo.hProcess!= (IntPtr)0 &amp;&amp; processInfo.hProcess!= (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
	  procSH.InitialSetHandle(processInfo.hProcess);
   if ( processInfo.hThread != (IntPtr)0 &amp;&amp; processInfo.hThread != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
	  threadSH.InitialSetHandle(processInfo.hThread);
}</pre>
<p>This is from <code>StartWithCreateProcess()</code>, a private method of <code>Process</code>. So no surprises that it&#8217;s doing a bunch of Win32 native API calls. What stands out is the <code>try{}</code> construct. But also notice the <a href=" http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.runtimehelpers.prepareconstrainedregions.aspx"><code>RuntimeHelpers.PrepareConstrainedRegions()</code></a> call.</p>
<p>Thinking of possible reasons for this, I suspected it had to do with run-time guarantees. The <code>RuntimeHelpers.PrepareConstrainedRegions()</code> call is a member of CER. So why the need to use empty try if we have the PrepareConstrainedRegions call? Regrettably, I confused it with the empty <code>try</code> clause. In reality, the empty try construct has nothing to do with CER and everything with execution interruption by means of <a href="http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception(v=vs.100).aspx">ThreadAbortException</a>.</p>
<p>A quick search hit Siddharth Uppal&#8217;s <em><a href="http://blog.somecreativity.com/2008/04/10/the-empty-try-block-mystery/">The empty try block mystery</a></em> where he explains that <code>Thread.Abort()</code> never interrupts code in the <code>finally</code> clause. Well, not quite.</p>
<h2>Thread.Abort and finally</h2>
<p>A common interview question, after going through the semantics of <code>try</code>/<code>catch</code>/<code>finally</code>, is to ask the candidate if <code>finally</code> is <em>always</em> executed (since usually that&#8217;s the wording they use). Are there no scenarios where one could conceivably expect their code in <code>finally</code> never to get executed? A creative response is usually when we have an an &#8220;infinite loop&#8221; in the <code>try</code> or <code>catch</code> (if it gets called). Novice candidates are easily confused when they consider a premature termination of the process (or thread). After all, one would expect that there be some consistency in the behavior of code. So why shouldn&#8217;t <code>finally</code> <em>always</em> get executed, even in a <em>process</em> termination scenario?</p>
<p>It&#8217;s not difficult to see that there is a struggle of powers between the termination party and the code/process in question. If <code>finally</code> always executes, there would be no guarantees for termination. Yes, we cannot guarantee both that <code>finally</code> will always execute while guaranteeing that termination will always succeed. One or both must have weak guarantees (or at least weaker guarantees than the other). When push comes to shove, we (as users or administrators) want to have full control over our machines, so we choose to have the ultimate magic wand to kill and terminate any misbehaving (or just undesirable) process.</p>
<p>The story is a little bit different when it comes to aborting individual threads, however. Where on the process level the operating system can terminate it with a sweeping gesture, in the managed world things are more controlled. The CLR can see to it that any thread that is about to get terminated (by a call to <code>Thread.Abort()</code>) is done cleanly and respecting all the language and runtime rules. This includes executing finally blocks as well as <a href="http://blogs.msdn.com/b/cbrumme/archive/2004/02/20/77460.aspx">finalizers</a>.</p>
<h3>ThreadAbortException weirdness</h3>
<p>When <a href="http://blogs.msdn.com/b/dotnet/archive/2009/04/28/threadabortexception.aspx">aborting a thread</a>, the apparent behavior is one of an exception thrown from <em>within</em> the thread in question. When <em>another</em> thread invokes <code>Thread.Abort()</code> on <em>our</em> thread, a <code>ThreadAbortException</code> is raised from <em>our</em> thread code. This is called asynchronous thread abort, as opposed to synchronous abort, when a thread invokes <code>Thread.CurrentThread.Abort()</code> (invariantly on itself). Other asynchronous exceptions include OutOfMemoryException and StackOverflowException.</p>
<p>The behavior, then, is exactly as one would expect when an exception is raised. The exception bubbles up the stack, executing <code>catch</code> and <code>finally</code> blocks as one would expect from any other exception. There are, however, a couple of crucial differences between <code>ThreadAbortException</code> and other Exceptions (with the exception of <a href="http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx">StackOverflowException</a>, which can&#8217;t be caught at all). First, this exception can&#8217;t be suppressed by simply catching it &#8211; it is automatically rethrown right after exiting the <code>catch</code> clause that caught it. Second, throwing it does <em>not</em> abort the running thread (it must be done via a call to <code>Thread.Abort()</code>).</p>
<p>The source for this behavior of <code>ThreadAbortException</code> is the abort requested flag, which is set when <code>Thread.Abort()</code> is invoked (but not when it is thrown directly). CLR then checks for this flag at certain check-points and proceeds to raise the exception, which normally is raised between any two <em>machine</em> instructions. This guarantees that the exception will not get thrown when executing a finally block or when executing unmanaged code.</p>
<p>So the expectation of the novice interviewee (and Mr. Uppal&#8217;s) was right after all. Except, it wasn&#8217;t. We are back full circle to the problem between the purpose of aborting a thread, and the possibility of an ill behaved code never giving up at all. I am being too generous when I label code that wouldn&#8217;t yield to a request to abort as &#8220;ill behaved.&#8221; Because <code>ThreadAbortException</code> is automatically rethrown from <code>catch</code> causes, the only way to suppress it is to explicitly call <code>Thread.ResetAbort()</code> which clears the abort requested flag. This is intentional as developers are in the habit of writing catching-all clauses very frequently.</p>
<h2>AppDomain hosting</h2>
<p>So far we&#8217;ve assumed that we just might need to terminate a process, no questions asked. But why would one need to abort individual threads within a process? The answer lies with <a href="http://blogs.msdn.com/b/cbrumme/archive/2004/02/21/77595.aspx">hosting</a>. In environments such as IIS or SQL servers, the server should be both fast and reliable. This led to the design of compartmentalizing processes beyond threads. <a href="http://msdn.microsoft.com/en-us/library/2bh4z9hs(v=vs.100).aspx"><code>AppDomain</code></a> groups processing units within a single process such that spawning new instances is fast (faster than spawning a complete new process,) but at the same time it&#8217;s grouped such that they can be unloaded on demand. When an <code>AppDomain</code> instance takes longer than the configured time (or consumes some resource more than it should,) it&#8217;s deemed ill-behaved and the server will want to unload it. Unloading includes aborting every thread within the <code>AppDomain</code> in question.</p>
<p>The problem is yet again one of conflict between guarantees. This time, though, the termination logic <em>needs</em> to play along, or else. When terminating a process, the complete process memory is released, along with all its system resources. If the managed code or CLR don&#8217;t do that, the operating system will. In a hosted execution environment, the host wants to have full control over the life-time of an <code>AppDomain</code> (with all its threads,) all the while, when it decides to purge of it, it does not want to destabilize the process or, worse, itself or the system at large. When unloading an <code>AppDomain</code>, the server wants to give it a chance to cleanup and release any shared resources, including files and sockets and synchronization objects (i.e. locks,) to name but a few. This is because the process will continue running, hopefully for a very long time. Hence the behavior of <code>ThreadAbortException</code> that calls every <code>catch</code> and <code>finally</code> as it should.</p>
<p>In return, any process that wants to play rough gets to call <code>Thread.ResetAbort()</code> and go on with its life, thereby defeating the control that the server enjoyed. The server invariantly has the upper hand, of course. After a second limit is exceeded, after invoking <code>Thread.Abort()</code>, in the words of Tarantino, the server may &#8220;<a href="http://www.urbandictionary.com/define.php?term=go%20medieval">go medieval</a>&#8221; on the misbehaving <code>AppDomain</code>.</p>
<h2>Rude Abort/Unload/Exit</h2>
<p>When a thread requested to abort doesn&#8217;t play along, it warrants rudeness. The CLR allows a host to specify <a href="http://msdn.microsoft.com/en-us/magazine/cc163298.aspx">escalation policy</a> in similar events, such that the host would escalate a normal thread abort into a <em>rude</em> thread abort. Similarly, a normal <code>AppDomain</code> unload and process exit may be escalated to a rude ones.</p>
<p>But we all know that the server doesn&#8217;t want to be too inconsiderate. It wouldn&#8217;t want to jeopardize its stability in the wake of this arms race between it and the hosted <code>AppDomain</code>. For that, it wants to have some guarantees. More stringent guarantees from the code in question that it will not misbehave again, when given half a chance. One such guarantee is that the finalization code will not have ill side-effects.</p>
<p>In a rude thread abort event, the CLR <a href="http://stackoverflow.com/questions/7064811/why-is-thread-not-interrupted-when-sleeping-in-finally-block ">forgoes calling any finally blocks</a> (except those marked as Constrained Execution Regions, or CER for short) as well as any normal finalizer. But unlike mere finally blocks, finalizers are a much more serious bunch. They are functions with consequences. Recall that finalization serves the purpose of releasing system resources. In a completely managed environment, with garbage collection and cleanup, the only resources that needs special care are those that <em>aren&#8217;t</em> managed. In an ideal scenario, one wouldn&#8217;t need to implement finalizers at all. The case is different when we need to wrap a system resource that is not managed (this includes native DLL invoking). All system resources that are represented by the framework are released precisely using a finalizer.</p>
<p>Admittedly, if we are developing standalone applications, as opposed to hosted, we don&#8217;t have to worry about the possibility of escalation and rude abort or unload. But then again, why should we worry about <code>Thread.Abort()</code> at all in such a case? Either our code could issue such a harsh request, which we should avoid like the plague and opt to more civil cancellation methods, such as raising events or setting shared flags (with some special care), or, our code is in a library that may be called either from a standalone application or a hosted one. Only in the latter case must we worry and prepare for the possibility of rude abort/unload.</p>
<h2>Critical Finalization and CER</h2>
<p><code>Dispose()</code> is called in <code>finally</code> blocks, either manually us via the <code>using</code> clause. So the only correct way to dispose objects during such an upheaval is to have finalizers on these objects. And not just any finalizer, but <a href="http://msdn.microsoft.com/en-us/library/system.runtime.constrainedexecution.criticalfinalizerobject.aspx">Critical Finalizers</a>. This is the same technique used in <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.aspx">SafeHandle</a> to ensure that native handles are correctly released in the event of a catastrophic failure.</p>
<p>When things get serious, only <a href="http://blogs.msdn.com/b/bclteam/archive/2005/06/14/429181.aspx">finalizers marked as safe</a> are called. Unsurprisingly, attributes are used to mark methods as safe. The contract between CLR and the code is a strict one. First, we communicate how critical a function is, in the face of asynchronous exceptions by marking their reliability. Next, we void our rights to allocate memory, which isn&#8217;t trivial, since this is done transparently in some cases such as P/Invoke marshaling, locking and boxing. In addition, the only methods we can call from within a CER block are those with strong reliability guarantees. Virtual methods that aren&#8217;t prepared in advance cannot be called either.</p>
<p>This brings us full circle to <code>RuntimeHelpers.PrepareConstrainedRegions()</code>. What this call does is it tells the CLR to fully prepare the proceeding code, by allocating all necessary memory, ensuring there is sufficient stack space, JITing the code, which completely loads any assemblies we may need.</p>
<p><a href="http://stackoverflow.com/questions/1101147/code-demonstrating-the-importance-of-a-constrained-execution-region">Here is a sample code</a> that demonstrates how this works in practice. When the ReliabilityContract attribute is commented out, the try block is executed before the finally block, which fails. However, with the ReliabilityContract attribute, the <code>PrepareConstrainedRegions()</code> call fails to allocate all necessary memory beforehand and therefore doesn&#8217;t even attempt to execute the try clause, nor the finally, instead the exception is thrown immediately.</p>
<p>There are three forms to execute code in Constrained Execution Regions (from the <a href="http://blogs.msdn.com/bclteam/archive/2005/06/14/429181.aspx">BCL Team Blog</a>):</p>
<ul>
<li>ExecuteCodeWithGuaranteedCleanup, a stack-overflow safe form of a try/finally.</li>
<li>A try/finally block preceded immediately by a call to RuntimeHelpers.PrepareConstrainedRegions. The try block is not constrained, but all catch, finally, and fault blocks for that try are.</li>
<li>As a critical finalizer &#8211; any subclass of CriticalFinalizerObject has a finalizer that is eagerly prepared before an instance of the object is allocated.
<ul>
<li>A special case is SafeHandle&#8217;s ReleaseHandle method, a virtual method that is eagerly prepared before the subclass is allocated, and called from SafeHandle&#8217;s critical finalizer.</li>
</ul>
</li>
</ul>
<h2>Conclusion</h2>
<p>Normally, CLR guarantees clean execution and cleanup (via finally and finalization code) even in the face of asynchronous exceptions and thread abort. However it does preserve the right to take a harsher measure if the host escalates things. Writing code in finally blocks to avoid dealing with the possibility of asynchronous exceptions, while <a href="http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=c1898a31-a0aa-40af-871c-7847d98f1641">not the best practice</a>, will work. When we abuse this, by reseting abort requests and spending too long in finally blocks, the host will escalate things to rude unload and will <a href="http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=f9a1d4c8-553b-4cc1-b1d6-0a8c395d8e9c">aggressively rip the AppDomain with all its threads, bypassing finally blocks</a>, unless in a CER block, as the above code did.</p>
<p>So, finally blocks are not executed when a rude abort/unload is in progress (unless in CER), when the process is terminated (by the operating system), when an unhandled exception is raised (typically in unmanaged code or in the CLR) or in background threads (IsBackground == true) when all foreground threads have exited.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.ashodnakashian.com%2F2013%2F03%2Fthread-abort-and-critical-regions-in-net%2F&amp;title=Thread%20Abort%20and%20Critical%20Regions%20%28in%20.Net%29" id="wpa2a_18"><img src="http://blog.ashodnakashian.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KYMnCSAeqhg:YxDZGFjtIKg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=KYMnCSAeqhg:YxDZGFjtIKg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KYMnCSAeqhg:YxDZGFjtIKg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KYMnCSAeqhg:YxDZGFjtIKg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=KYMnCSAeqhg:YxDZGFjtIKg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KYMnCSAeqhg:YxDZGFjtIKg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=KYMnCSAeqhg:YxDZGFjtIKg:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KYMnCSAeqhg:YxDZGFjtIKg:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KYMnCSAeqhg:YxDZGFjtIKg:l6gmwiTKsz0"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=l6gmwiTKsz0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=KYMnCSAeqhg:YxDZGFjtIKg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ashodnakashian/zpMw/~4/KYMnCSAeqhg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.ashodnakashian.com/2013/03/thread-abort-and-critical-regions-in-net/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.ashodnakashian.com/2013/03/thread-abort-and-critical-regions-in-net/</feedburner:origLink></item>
		<item>
		<title>Free Education</title>
		<link>http://feedproxy.google.com/~r/ashodnakashian/zpMw/~3/OIij-_B_1ic/</link>
		<comments>http://blog.ashodnakashian.com/2013/03/free-education/#comments</comments>
		<pubDate>Sun, 10 Mar 2013 22:23:57 +0000</pubDate>
		<dc:creator>Ashod Nakashian</dc:creator>
				<category><![CDATA[Lectures]]></category>
		<category><![CDATA[Sophia]]></category>

		<guid isPermaLink="false">http://blog.ashodnakashian.com/?p=2033</guid>
		<description><![CDATA[A while back I wrote about free online courses (on more than one occasion). Back then I had somehow managed to find the time to go through not one, but three Stanford courses simultaneously. All three were of very high quality, in many respects. Around the turn of the century some universities had started making <a href='http://blog.ashodnakashian.com/2013/03/free-education/' class='excerpt-more'>[...]</a>]]></description>
				<content:encoded><![CDATA[<p>A while back I wrote about free <a href="http://blog.ashodnakashian.com/?p=1707">online courses</a> (on <a href="http://blog.ashodnakashian.com/?p=1221">more than one</a> occasion). Back then I had somehow managed to find the time to go through not one, but three Stanford courses simultaneously. All three were of very high quality, in many respects.</p>
<p>Around the turn of the century some universities had started making their lectures available to the general public. This was a reasonable and predictable next-step from merely video taping the lectures for the on-campus (paying) students who had missed any or, well, just to make lectures more accessible. The cost of filming and editing these lectures are uncured once, so why not capitalize on it and make them available world-wide? It&#8217;d seem that this is how things started, with the possible hope of growing this into an e-learning branch that could make the university money, or, failing that, at least prove a good promotional campaign for more studentship.</p>
<p>The problem with this approach, from the student&#8217;s point of view, is that the lecture itself typically assumes in-person attendance. Even with the knowledge of the possibility of someone watching the replay having not personally attended, it was targeted to on-campus students who could meet with TAs or colleagues to get notes and other materials they missed. Also, any copyrighted materials were completely stripped away from these videos, to avoid any legal complications. (This was annoying in a sociology class that I was taking because all the social experiment videos were removed from the lectures.)</p>
<p>Enter Stanford and <a href="https://www.coursera.org/">Coursera</a>. The vision was free education primarily for the online viewer, wherever they may be. This meant a different format altogether. The presenter isn&#8217;t just walking about, talking to an audience of coming-and-going students (which I find very distracting even when watching at home,) rather they are prepared with material and equipment to explain theory and, where applicable, demo the concepts with experiments or walk-through. All of which is clear and legible. Coursera, an off-shoot of Stanford took this to the next logical step: a dedicated education platform for generation-next. I do not doubt that they could (if they already don&#8217;t) commercialize the platform by licensing to universities to cater for on-campus and online students alike.</p>
<p>As the offerings started to grow, some sites started aggregating online and free education sites. One particular site that was brought to my attention by a member of their team is <a href="http://www.onlinecourses.com">OnlineCourses.com</a>, which makes hundreds of courses reachable by listing, searching and creating custom course lists with the ability to track one&#8217;s progress as well. They also include reputable schools including Stanford, Yale and Harvard, among others. Coursera too has managed to grow their portfolio of subjects greatly as well. From a mere handful at the time of their start to possibly hundreds as I write.</p>
<p>A trait that makes OnlineCourses.com stand out is perhaps that they aggregate not just video lectures, but audio-only and text-only as well, which are differentiated by icons next to each. For someone interested in studying certain subject from reading notes, rather than by taking notes, text-only courses might be more suitable. For those who like to listen while working out or commuting, audio-only might be better suited, as the lecturer presumably would not refer to visual objects that the listener can&#8217;t see.</p>
<p>The state of online, free, e-learning resources is an embarrassment of riches. The three Stanford courses that I took, which admittedly required some extra reading and doing homework, took anywhere between 20 to 25 hours/week, including watching the lectures. With subjects spanning art, music and creative writing, to quantum physics and molecular biology, available from numerous universities, in some cases in multiple languages, taught by actual teaching professors, reviewing and choosing which to view (even casually and as a matter of interest) is time consuming (albeit, fun). Not to mention committing and actually putting in the effort and hours necessary to complete them.</p>
<p>It is truly amazing time this one we live in. No longer do we have to wonder about (or regret) the courses we didn&#8217;t (or couldn&#8217;t) take at school. We can, with the help of technology, visit these virtual classrooms to the content of our hearts. Even a casual, electronic attendance of 30-45 minutes a day can be very rewarding and, hopefully, fun.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.ashodnakashian.com%2F2013%2F03%2Ffree-education%2F&amp;title=Free%20Education" id="wpa2a_20"><img src="http://blog.ashodnakashian.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=OIij-_B_1ic:73d2ptFLx7w:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=OIij-_B_1ic:73d2ptFLx7w:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=OIij-_B_1ic:73d2ptFLx7w:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=OIij-_B_1ic:73d2ptFLx7w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=OIij-_B_1ic:73d2ptFLx7w:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=OIij-_B_1ic:73d2ptFLx7w:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?i=OIij-_B_1ic:73d2ptFLx7w:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=OIij-_B_1ic:73d2ptFLx7w:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=OIij-_B_1ic:73d2ptFLx7w:l6gmwiTKsz0"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=l6gmwiTKsz0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?a=OIij-_B_1ic:73d2ptFLx7w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ashodnakashian/zpMw?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ashodnakashian/zpMw/~4/OIij-_B_1ic" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.ashodnakashian.com/2013/03/free-education/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ashodnakashian.com/2013/03/free-education/</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced
Database Caching 13/19 queries in 0.326 seconds using disk
Object Caching 1107/1117 objects using disk

 Served from: blog.ashodnakashian.com @ 2013-05-18 16:30:33 by W3 Total Cache -->
