<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
	
	>
<channel>
	<title>Comments on: Smarter termination for thread racing</title>
	<atom:link href="http://conal.net/blog/posts/smarter-termination-for-thread-racing/feed" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing</link>
	<description>Inspirations &#38; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Sat, 26 Sep 2020 21:06:12 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.17</generator>
	<item>
		<title>By: Conal Elliott &#187; Blog Archive &#187; Another angle on functional future values</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comment-293</link>
		<dc:creator><![CDATA[Conal Elliott &#187; Blog Archive &#187; Another angle on functional future values]]></dc:creator>
		<pubDate>Tue, 06 Jan 2009 22:45:01 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=72#comment-293</guid>
		<description><![CDATA[&lt;p&gt;[...] About      &#171; Smarter termination for thread racing [...]&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>[&#8230;] About      &laquo; Smarter termination for thread racing [&#8230;]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Verswyvelen</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comment-292</link>
		<dc:creator><![CDATA[Peter Verswyvelen]]></dc:creator>
		<pubDate>Thu, 25 Dec 2008 14:09:53 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=72#comment-292</guid>
		<description><![CDATA[&lt;p&gt;Not sure if this helps, but if I replace&lt;/p&gt;

&lt;pre&gt;
amb :: a -&gt; a -&gt; IO a
amb = race `on` evaluate
&lt;/pre&gt;

&lt;p&gt;by&lt;/p&gt;

&lt;pre&gt;
amb :: a -&gt; a -&gt; IO a
amb = race `on` return
&lt;/pre&gt;

&lt;p&gt;I get back 1.&lt;/p&gt;

&lt;p&gt;But of course that might not be what you want, since the semantics of evaluate are different (I don&#039;t fully understand from the GHC documentation what evaluate really does...)&lt;/p&gt;

&lt;p&gt;If I replace amb by &quot;race &lt;code&gt;on&lt;/code&gt; (($!) return)&quot; I get the exception again&lt;/p&gt;

&lt;p&gt;I also made a version that hangs under GHCi instead of throwing the exception:&lt;/p&gt;

&lt;pre&gt;race :: IO a -&gt; IO a -&gt; IO a
race a b = bracket entry exit (takeMVar . fst)
    where
      entry = block $ do
                v &lt;- newEmptyMVar
                ta &lt;- forkIO (a &gt;&gt;= putMVar v)
                tb &lt;- forkIO (b &gt;&gt;= putMVar v)
                putStrLn (&quot;Waiting for either &quot;++show ta++&quot; or &quot;++show tb ++&quot;n&quot;)
                return (v,((ta,tb)))
      exit (v,((ta,tb))) = do
        putStrLn (&quot;Killing &quot;++show ta++&quot;n&quot;)
        killThread ta
        putStrLn (&quot;Killing &quot;++show tb++&quot;n&quot;)
        killThread tb
        putStrLn (&quot;Killed request send to &quot;++show ta++&quot; and &quot;++show tb++&quot;n&quot;)
&lt;/pre&gt;

&lt;p&gt;The version above - when run via GHCi - blocks. If I press CTRL-C it interrupts. When running again in the same session, I get 1. When running a compiled version without optimization, I get the exception. When running a compile version with optimization, I get 1.&lt;/p&gt;

&lt;p&gt;Weird behavior...&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Not sure if this helps, but if I replace</p>

<pre>
amb :: a -&gt; a -&gt; IO a
amb = race `on` evaluate
</pre>

<p>by</p>

<pre>
amb :: a -&gt; a -&gt; IO a
amb = race `on` return
</pre>

<p>I get back 1.</p>

<p>But of course that might not be what you want, since the semantics of evaluate are different (I don&#8217;t fully understand from the GHC documentation what evaluate really does&#8230;)</p>

<p>If I replace amb by &#8220;race <code>on</code> (($!) return)&#8221; I get the exception again</p>

<p>I also made a version that hangs under GHCi instead of throwing the exception:</p>

<pre>race :: IO a -&gt; IO a -&gt; IO a
race a b = bracket entry exit (takeMVar . fst)
    where
      entry = block $ do
                v &lt;- newEmptyMVar
                ta &lt;- forkIO (a &gt;&gt;= putMVar v)
                tb &lt;- forkIO (b &gt;&gt;= putMVar v)
                putStrLn ("Waiting for either "++show ta++" or "++show tb ++"n")
                return (v,((ta,tb)))
      exit (v,((ta,tb))) = do
        putStrLn ("Killing "++show ta++"n")
        killThread ta
        putStrLn ("Killing "++show tb++"n")
        killThread tb
        putStrLn ("Killed request send to "++show ta++" and "++show tb++"n")
</pre>

<p>The version above &#8211; when run via GHCi &#8211; blocks. If I press CTRL-C it interrupts. When running again in the same session, I get 1. When running a compiled version without optimization, I get the exception. When running a compile version with optimization, I get 1.</p>

<p>Weird behavior&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Verswyvelen</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comment-291</link>
		<dc:creator><![CDATA[Peter Verswyvelen]]></dc:creator>
		<pubDate>Thu, 25 Dec 2008 00:09:52 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=72#comment-291</guid>
		<description><![CDATA[&lt;p&gt;Well, I tried the following version:&lt;/p&gt;

&lt;pre&gt;race :: IO a -&gt; IO a -&gt; IO a
race a b = bracket entry exit (return . fst)
    where
      entry = block $ do
                v &lt;- newEmptyMVar
                ta &lt;- forkIO (a &gt;&gt;= putMVar v)
                tb &lt;- forkIO (b &gt;&gt;= putMVar v)
                x &lt;- takeMVar v
                return (x,((ta,tb)))
      exit (_,((ta,tb))) = do
        killThread ta
        killThread tb

&lt;/pre&gt;

&lt;p&gt;Using GHCi or GHC --make, I get the thread killed exception...&lt;/p&gt;

&lt;p&gt;When using GHC --make -O, I don&#039;t get the  thread killed exception, just get the correct answer 1&lt;/p&gt;

&lt;p&gt;Sometimes, using GHCi, it just blocks.&lt;/p&gt;

&lt;p&gt;I get the same with Spencer&#039;s version... Haven&#039;t tried the other versions, but I expect they will also behave correctly with GHC -O...&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Well, I tried the following version:</p>

<pre>race :: IO a -&gt; IO a -&gt; IO a
race a b = bracket entry exit (return . fst)
    where
      entry = block $ do
                v &lt;- newEmptyMVar
                ta &lt;- forkIO (a &gt;&gt;= putMVar v)
                tb &lt;- forkIO (b &gt;&gt;= putMVar v)
                x &lt;- takeMVar v
                return (x,((ta,tb)))
      exit (_,((ta,tb))) = do
        killThread ta
        killThread tb

</pre>

<p>Using GHCi or GHC &#8211;make, I get the thread killed exception&#8230;</p>

<p>When using GHC &#8211;make -O, I don&#8217;t get the  thread killed exception, just get the correct answer 1</p>

<p>Sometimes, using GHCi, it just blocks.</p>

<p>I get the same with Spencer&#8217;s version&#8230; Haven&#8217;t tried the other versions, but I expect they will also behave correctly with GHC -O&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comment-290</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Wed, 24 Dec 2008 06:32:34 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=72#comment-290</guid>
		<description><![CDATA[&lt;p&gt;I&#039;ve been experimenting with various &lt;code&gt;race&lt;/code&gt; implementations, including the ones given above.
All of these smarter versions break when given the following example:&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;test :: &lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Int&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;color: #833; font-weight: bold;&quot;&gt;Int&lt;/span&gt;&lt;/a&gt;
test = f &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;f &lt;span style=&quot;color: red;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;where&lt;/span&gt; f v = &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;v `unamb` &lt;span style=&quot;color: red;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; `&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:seq&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;seq&lt;/span&gt;&lt;/a&gt;` v&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;The error message (in ghci) is &quot;*** Exception: thread killed&quot;.&lt;/p&gt;

&lt;p&gt;Definitions that give this error include my three&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;a `race` b = &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt; v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                takeMVar v `finally` &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;killThread ta &gt;&gt; killThread tb&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt;
&#160;
a `race` b = &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt; v &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;&lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt; tb &lt;- forkPut b v
                    takeMVar v `finally` killThread tb&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt;
                 `finally` killThread ta
&#160;
a `race` b = &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt; v &lt;- newEmptyMVar
                forking &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;putCatch a v&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; $
                  forking &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;putCatch b v&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; $
                    takeMVar v&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;and Luke&#039;s:&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;race a b = &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt;
    v &lt;- newEmptyMVar
    block $ &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt;
        ta &lt;- forkPut a v
        tb &lt;- forkPut b v
        unblock &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;takeMVar v&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; `finally` &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;killThread ta &gt;&gt; killThread tb&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;and Spencer&#039;s:&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;race a b = &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt;
    v &lt;- newEmptyMVar
    &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;let&lt;/span&gt; t x = x &gt;&gt;= putMVar v
    withThread &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;t a&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; $ withThread &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;t b&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; $ takeMVar v
 &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;where&lt;/span&gt;
   withThread u v = bracket &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;forkIO u&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; killThread &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;const&lt;/span&gt;&lt;/a&gt; v&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;My original version gives the answer I want, namely 1:&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;a `race` b = &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt; v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                x  &lt;- takeMVar  v
                killThread ta
                killThread tb
                &lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;/a&gt; x&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Here&#039;s a definition that comes from inlining &lt;code&gt;finally&lt;/code&gt; in the first smart version above:&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;a `race` b = &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt; v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                block &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;&lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt;
                  x &lt;- unblock &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;takeMVar v&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; `onException` &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;killThread ta &gt;&gt; killThread tb&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt;
                  killThread ta &gt;&gt; killThread tb
                  &lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;/a&gt; x&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;It also fails.
However, if I remove the inner &lt;code&gt;unblock&lt;/code&gt;, I get 1, as desired:&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;a `race` b = &lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt; v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                block &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;&lt;span style=&quot;color: #050; font-weight: bold;&quot;&gt;do&lt;/span&gt;
                  x &lt;- &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;takeMVar v&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; `onException` &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;killThread ta &gt;&gt; killThread tb&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt;
                  killThread ta &gt;&gt; killThread tb
                  &lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;return&lt;/span&gt;&lt;/a&gt; x&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;What is going on here?
What is causing &quot;*** Exception: thread killed&quot;?&lt;/p&gt;

&lt;p&gt;Here is a possibly-relevant &lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html#12&quot; rel=&quot;nofollow&quot;&gt;excerpt from the documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Some operations are interruptible, which means that they can receive asynchronous exceptions even in the scope of a &lt;code&gt;block&lt;/code&gt;.  Any function which may itself block is defined as interruptible; this includes &lt;code&gt;Control.Concurrent.MVar.takeMVar&lt;/code&gt; (but not &lt;code&gt;Control.Concurrent.MVar.tryTakeMVar&lt;/code&gt;), and most operations which perform some I/O with the outside world.&lt;/p&gt;
&lt;/blockquote&gt;
]]></description>
		<content:encoded><![CDATA[<p>I&#8217;ve been experimenting with various <code>race</code> implementations, including the ones given above.
All of these smarter versions break when given the following example:</p>

<p><div>
<pre class="haskell">test :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Int" rel="nofollow"><span style="color: #833; font-weight: bold;">Int</span></a>
test = f <span style="color: green;">&#40;</span>f <span style="color: red;">1</span><span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span> f v = <span style="color: green;">&#40;</span>v `unamb` <span style="color: red;">1</span><span style="color: green;">&#41;</span> `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:seq" rel="nofollow"><span style="font-weight: bold;">seq</span></a>` v</pre>
</div></p>

<p>The error message (in ghci) is &#8220;*** Exception: thread killed&#8221;.</p>

<p>Definitions that give this error include my three</p>

<p><div>
<pre class="haskell">a `race` b = <span style="color: #050; font-weight: bold;">do</span> v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                takeMVar v `finally` <span style="color: green;">&#40;</span>killThread ta &gt;&gt; killThread tb<span style="color: green;">&#41;</span>
&nbsp;
a `race` b = <span style="color: #050; font-weight: bold;">do</span> v &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                <span style="color: green;">&#40;</span><span style="color: #050; font-weight: bold;">do</span> tb &lt;- forkPut b v
                    takeMVar v `finally` killThread tb<span style="color: green;">&#41;</span>
                 `finally` killThread ta
&nbsp;
a `race` b = <span style="color: #050; font-weight: bold;">do</span> v &lt;- newEmptyMVar
                forking <span style="color: green;">&#40;</span>putCatch a v<span style="color: green;">&#41;</span> $
                  forking <span style="color: green;">&#40;</span>putCatch b v<span style="color: green;">&#41;</span> $
                    takeMVar v</pre>
</div></p>

<p>and Luke&#8217;s:</p>

<p><div>
<pre class="haskell">race a b = <span style="color: #050; font-weight: bold;">do</span>
    v &lt;- newEmptyMVar
    block $ <span style="color: #050; font-weight: bold;">do</span>
        ta &lt;- forkPut a v
        tb &lt;- forkPut b v
        unblock <span style="color: green;">&#40;</span>takeMVar v<span style="color: green;">&#41;</span> `finally` <span style="color: green;">&#40;</span>killThread ta &gt;&gt; killThread tb<span style="color: green;">&#41;</span></pre>
</div></p>

<p>and Spencer&#8217;s:</p>

<p><div>
<pre class="haskell">race a b = <span style="color: #050; font-weight: bold;">do</span>
    v &lt;- newEmptyMVar
    <span style="color: #050; font-weight: bold;">let</span> t x = x &gt;&gt;= putMVar v
    withThread <span style="color: green;">&#40;</span>t a<span style="color: green;">&#41;</span> $ withThread <span style="color: green;">&#40;</span>t b<span style="color: green;">&#41;</span> $ takeMVar v
 <span style="color: #050; font-weight: bold;">where</span>
   withThread u v = bracket <span style="color: green;">&#40;</span>forkIO u<span style="color: green;">&#41;</span> killThread <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const" rel="nofollow"><span style="font-weight: bold;">const</span></a> v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>My original version gives the answer I want, namely 1:</p>

<p><div>
<pre class="haskell">a `race` b = <span style="color: #050; font-weight: bold;">do</span> v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                x  &lt;- takeMVar  v
                killThread ta
                killThread tb
                <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return" rel="nofollow"><span style="font-weight: bold;">return</span></a> x</pre>
</div></p>

<p>Here&#8217;s a definition that comes from inlining <code>finally</code> in the first smart version above:</p>

<p><div>
<pre class="haskell">a `race` b = <span style="color: #050; font-weight: bold;">do</span> v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                block <span style="color: green;">&#40;</span><span style="color: #050; font-weight: bold;">do</span>
                  x &lt;- unblock <span style="color: green;">&#40;</span>takeMVar v<span style="color: green;">&#41;</span> `onException` <span style="color: green;">&#40;</span>killThread ta &gt;&gt; killThread tb<span style="color: green;">&#41;</span>
                  killThread ta &gt;&gt; killThread tb
                  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return" rel="nofollow"><span style="font-weight: bold;">return</span></a> x<span style="color: green;">&#41;</span></pre>
</div></p>

<p>It also fails.
However, if I remove the inner <code>unblock</code>, I get 1, as desired:</p>

<p><div>
<pre class="haskell">a `race` b = <span style="color: #050; font-weight: bold;">do</span> v  &lt;- newEmptyMVar
                ta &lt;- forkPut a v
                tb &lt;- forkPut b v
                block <span style="color: green;">&#40;</span><span style="color: #050; font-weight: bold;">do</span>
                  x &lt;- <span style="color: green;">&#40;</span>takeMVar v<span style="color: green;">&#41;</span> `onException` <span style="color: green;">&#40;</span>killThread ta &gt;&gt; killThread tb<span style="color: green;">&#41;</span>
                  killThread ta &gt;&gt; killThread tb
                  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return" rel="nofollow"><span style="font-weight: bold;">return</span></a> x<span style="color: green;">&#41;</span></pre>
</div></p>

<p>What is going on here?
What is causing &#8220;*** Exception: thread killed&#8221;?</p>

<p>Here is a possibly-relevant <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html#12" rel="nofollow">excerpt from the documentation</a>:</p>

<blockquote>
  <p>Some operations are interruptible, which means that they can receive asynchronous exceptions even in the scope of a <code>block</code>.  Any function which may itself block is defined as interruptible; this includes <code>Control.Concurrent.MVar.takeMVar</code> (but not <code>Control.Concurrent.MVar.tryTakeMVar</code>), and most operations which perform some I/O with the outside world.</p>
</blockquote>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comment-289</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Sun, 21 Dec 2008 22:22:49 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=72#comment-289</guid>
		<description><![CDATA[&lt;p&gt;I&#039;m with you, Peter.  I&#039;d like a simple way to guarantee running the cleanup code.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>I&#8217;m with you, Peter.  I&#8217;d like a simple way to guarantee running the cleanup code.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Verswyvelen</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comment-288</link>
		<dc:creator><![CDATA[Peter Verswyvelen]]></dc:creator>
		<pubDate>Sun, 21 Dec 2008 19:12:49 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=72#comment-288</guid>
		<description><![CDATA[&lt;p&gt;Indeed. But I would like to see code that does not allow the process to exit before all of these thread finalizers did their cleanup code (since finalizers may run critical code, like turning off a nuclear power station to prevent a meltdown ;). Okay, not really an issue for Reactive.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Indeed. But I would like to see code that does not allow the process to exit before all of these thread finalizers did their cleanup code (since finalizers may run critical code, like turning off a nuclear power station to prevent a meltdown ;). Okay, not really an issue for Reactive.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comment-287</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Sat, 20 Dec 2008 05:51:57 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=72#comment-287</guid>
		<description><![CDATA[&lt;p&gt;Peter,&lt;/p&gt;

&lt;p&gt;I think the problem here is simply that the process exits before the threads all get a chance to terminate.  In my experiments, adding even a &lt;code&gt;yield&lt;/code&gt; to the end of &lt;code&gt;main&lt;/code&gt; seems to ensure that all threads get killed.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Peter,</p>

<p>I think the problem here is simply that the process exits before the threads all get a chance to terminate.  In my experiments, adding even a <code>yield</code> to the end of <code>main</code> seems to ensure that all threads get killed.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Verswyvelen</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comment-286</link>
		<dc:creator><![CDATA[Peter Verswyvelen]]></dc:creator>
		<pubDate>Fri, 19 Dec 2008 17:38:39 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=72#comment-286</guid>
		<description><![CDATA[&lt;p&gt;Mmm, I used Spencer&#039;s version, and added some more detail, but I still get the problem (it now does work with -threaded and +RTS -N2...). So the interpreted version kills all threads, the compiled version only does it with +RTS -N2, or at least the last putStrLn does not seem to be called.&lt;/p&gt;

&lt;p&gt;Ugly code follows:&lt;/p&gt;

&lt;pre&gt;import Prelude hiding (catch)

import Control.Concurrent
import Control.Concurrent.MVar
import Control.Exception
import System.IO
import Data.Char

withThread a b = bracket (forkIO a) kill (const b)
    where
      kill id = do
        putStrLn (&quot;Killing &quot;++show id++&quot;n&quot;)
        killThread id
        putStrLn (&quot;Killed &quot;++show id++&quot;n&quot;)

race a b = do
    v &lt;- newEmptyMVar
    let t x = x &gt;&gt;= putMVar v
    withThread (t a) $ withThread (t b) $ takeMVar v

forkPut :: IO a -&gt; MVar a -&gt; IO ThreadId
forkPut act v = forkIO ((act &gt;&gt;= putMVar v) `catch` uhandler `catch` bhandler)
 where
   uhandler (ErrorCall &quot;Prelude.undefined&quot;) = return ()
   uhandler err                             = throw err
   bhandler BlockedOnDeadMVar               = return ()

sleep n = do
  tid &lt;- myThreadId
  putStrLn (&quot;Sleeping &quot;++show n++&quot; sec on &quot;++show tid++&quot;n&quot;)
  threadDelay (n*1000000)
  putStrLn (&quot;Slept &quot;++show n++&quot; sec on &quot;++show tid++&quot;n&quot;)

f = sleep 2 `race` sleep 3

g = f `race` sleep 1

main = do
  hSetBuffering stdout LineBuffering
  g
&lt;/pre&gt;

&lt;p&gt;Output with GHCI:&lt;/p&gt;

&lt;pre&gt;
C:temp&gt;runghc racetest
Sleeping 1 sec on ThreadId 26
Sleeping 2 sec on ThreadId 27
Sleeping 3 sec on ThreadId 28
Slept 1 sec on ThreadId 26
Killing ThreadId 26
Killed ThreadId 26
Killing ThreadId 25
Killed ThreadId 25
&lt;b&gt;Killing ThreadId 28
Killed ThreadId 28&lt;/b&gt;
&lt;/pre&gt;

&lt;p&gt;Output from compiled EXE:&lt;/p&gt;

&lt;pre&gt;
C:temp&gt; racetest
Sleeping 1 sec on ThreadId 5
Sleeping 3 sec on ThreadId 7
Sleeping 2 sec on ThreadId 6
Slept 1 sec on ThreadId 5
Killing ThreadId 5
Killed ThreadId 5
Killing ThreadId 4
Killed ThreadId 4
&lt;b&gt;Killing ThreadId 7&lt;/b&gt;
&lt;/pre&gt;

&lt;p&gt;So &quot;Killed ThreadId 7&quot; is &lt;em&gt;not&lt;/em&gt; printed&lt;/p&gt;

&lt;p&gt;Output with +RTS -N2:&lt;/p&gt;

&lt;pre&gt;
C:temp&gt; racetest +RTS -N2
Sleeping 1 sec on ThreadId 5
Sleeping 3 sec on ThreadId 7
Sleeping 2 sec on ThreadId 6
Slept 1 sec on ThreadId 5

Killing ThreadId 5
Killed ThreadId 5
Killing ThreadId 4
Killed ThreadId 4
&lt;b&gt;Killing ThreadId 7
Killed ThreadId 7&lt;/b&gt;
&lt;/pre&gt;
]]></description>
		<content:encoded><![CDATA[<p>Mmm, I used Spencer&#8217;s version, and added some more detail, but I still get the problem (it now does work with -threaded and +RTS -N2&#8230;). So the interpreted version kills all threads, the compiled version only does it with +RTS -N2, or at least the last putStrLn does not seem to be called.</p>

<p>Ugly code follows:</p>

<pre>import Prelude hiding (catch)

import Control.Concurrent
import Control.Concurrent.MVar
import Control.Exception
import System.IO
import Data.Char

withThread a b = bracket (forkIO a) kill (const b)
    where
      kill id = do
        putStrLn ("Killing "++show id++"n")
        killThread id
        putStrLn ("Killed "++show id++"n")

race a b = do
    v &lt;- newEmptyMVar
    let t x = x &gt;&gt;= putMVar v
    withThread (t a) $ withThread (t b) $ takeMVar v

forkPut :: IO a -&gt; MVar a -&gt; IO ThreadId
forkPut act v = forkIO ((act &gt;&gt;= putMVar v) `catch` uhandler `catch` bhandler)
 where
   uhandler (ErrorCall "Prelude.undefined") = return ()
   uhandler err                             = throw err
   bhandler BlockedOnDeadMVar               = return ()

sleep n = do
  tid &lt;- myThreadId
  putStrLn ("Sleeping "++show n++" sec on "++show tid++"n")
  threadDelay (n*1000000)
  putStrLn ("Slept "++show n++" sec on "++show tid++"n")

f = sleep 2 `race` sleep 3

g = f `race` sleep 1

main = do
  hSetBuffering stdout LineBuffering
  g
</pre>

<p>Output with GHCI:</p>

<pre>
C:temp&gt;runghc racetest
Sleeping 1 sec on ThreadId 26
Sleeping 2 sec on ThreadId 27
Sleeping 3 sec on ThreadId 28
Slept 1 sec on ThreadId 26
Killing ThreadId 26
Killed ThreadId 26
Killing ThreadId 25
Killed ThreadId 25
<b>Killing ThreadId 28
Killed ThreadId 28</b>
</pre>

<p>Output from compiled EXE:</p>

<pre>
C:temp&gt; racetest
Sleeping 1 sec on ThreadId 5
Sleeping 3 sec on ThreadId 7
Sleeping 2 sec on ThreadId 6
Slept 1 sec on ThreadId 5
Killing ThreadId 5
Killed ThreadId 5
Killing ThreadId 4
Killed ThreadId 4
<b>Killing ThreadId 7</b>
</pre>

<p>So &#8220;Killed ThreadId 7&#8243; is <em>not</em> printed</p>

<p>Output with +RTS -N2:</p>

<pre>
C:temp&gt; racetest +RTS -N2
Sleeping 1 sec on ThreadId 5
Sleeping 3 sec on ThreadId 7
Sleeping 2 sec on ThreadId 6
Slept 1 sec on ThreadId 5

Killing ThreadId 5
Killed ThreadId 5
Killing ThreadId 4
Killed ThreadId 4
<b>Killing ThreadId 7
Killed ThreadId 7</b>
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Verswyvelen</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comment-285</link>
		<dc:creator><![CDATA[Peter Verswyvelen]]></dc:creator>
		<pubDate>Fri, 19 Dec 2008 17:20:00 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=72#comment-285</guid>
		<description><![CDATA[&lt;p&gt;Hi Conal,&lt;/p&gt;

&lt;p&gt;Nice to see it works. Simon Marlow also replied on your question. He posted code for the timeout function, which does something similar. See http://darcs.haskell.org/packages/base/System/Timeout.hs&lt;/p&gt;

&lt;p&gt;At home I played a bit with the bracket function and tested the following code:&lt;/p&gt;

&lt;pre&gt;import Prelude hiding (catch)

import Control.Concurrent
import Control.Concurrent.MVar
import Control.Exception
import System.IO
import Data.Char

a `race` b = do bracket entry exit (takeMVar.fst) 
    where
      entry = do
               v  &lt;- newEmptyMVar
               ta &lt;- forkPut a v
               tb &lt;- forkPut b v
               return (v,(ta,tb))

      exit (_,(ta,tb)) = do
        putChar &#039;a&#039;
        killThread ta
        putChar &#039;b&#039;
        killThread tb
        putChar &#039;c&#039;

forkPut :: IO a -&gt; MVar a -&gt; IO ThreadId
forkPut act v = forkIO ((act &gt;&gt;= putMVar v) `catch` uhandler `catch` bhandler)
 where
   uhandler (ErrorCall &quot;Prelude.undefined&quot;) = return ()
   uhandler err                             = throw err
   bhandler BlockedOnDeadMVar               = return ()

sleep n = putChar (intToDigit n) &gt;&gt; threadDelay (n*1000000) &gt;&gt; putChar (intToDigit n)

f = sleep 2 `race` sleep 3

g = f `race` sleep 1

main = do
  hSetBuffering stdout NoBuffering
  g
&lt;/pre&gt;

&lt;p&gt;Now, under Windows, when I run this with GHCI, I get 1231abcabc, as expected.&lt;/p&gt;

&lt;p&gt;But when compiling with ghc, and running the EXE, I get 1231abacb.&lt;/p&gt;

&lt;p&gt;I&#039;m missing a &#039;c&#039;, which might mean some tb thread is &lt;em&gt;not&lt;/em&gt; killed...&lt;/p&gt;

&lt;p&gt;When compiling with GHC -threaded and running the EXE (with or without +RTS -N2), I get 1231abacbc, so correct again.&lt;/p&gt;

&lt;p&gt;Bob has similar problems under OSX, he just got abc...&lt;/p&gt;

&lt;p&gt;What did I do wrong? Might this indicate a bug in GHC&#039;s runtime?&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Hi Conal,</p>

<p>Nice to see it works. Simon Marlow also replied on your question. He posted code for the timeout function, which does something similar. See <a href="http://darcs.haskell.org/packages/base/System/Timeout.hs" rel="nofollow">http://darcs.haskell.org/packages/base/System/Timeout.hs</a></p>

<p>At home I played a bit with the bracket function and tested the following code:</p>

<pre>import Prelude hiding (catch)

import Control.Concurrent
import Control.Concurrent.MVar
import Control.Exception
import System.IO
import Data.Char

a `race` b = do bracket entry exit (takeMVar.fst) 
    where
      entry = do
               v  &lt;- newEmptyMVar
               ta &lt;- forkPut a v
               tb &lt;- forkPut b v
               return (v,(ta,tb))

      exit (_,(ta,tb)) = do
        putChar 'a'
        killThread ta
        putChar 'b'
        killThread tb
        putChar 'c'

forkPut :: IO a -&gt; MVar a -&gt; IO ThreadId
forkPut act v = forkIO ((act &gt;&gt;= putMVar v) `catch` uhandler `catch` bhandler)
 where
   uhandler (ErrorCall "Prelude.undefined") = return ()
   uhandler err                             = throw err
   bhandler BlockedOnDeadMVar               = return ()

sleep n = putChar (intToDigit n) &gt;&gt; threadDelay (n*1000000) &gt;&gt; putChar (intToDigit n)

f = sleep 2 `race` sleep 3

g = f `race` sleep 1

main = do
  hSetBuffering stdout NoBuffering
  g
</pre>

<p>Now, under Windows, when I run this with GHCI, I get 1231abcabc, as expected.</p>

<p>But when compiling with ghc, and running the EXE, I get 1231abacb.</p>

<p>I&#8217;m missing a &#8216;c&#8217;, which might mean some tb thread is <em>not</em> killed&#8230;</p>

<p>When compiling with GHC -threaded and running the EXE (with or without +RTS -N2), I get 1231abacbc, so correct again.</p>

<p>Bob has similar problems under OSX, he just got abc&#8230;</p>

<p>What did I do wrong? Might this indicate a bug in GHC&#8217;s runtime?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Chung-chieh Shan</title>
		<link>http://conal.net/blog/posts/smarter-termination-for-thread-racing#comment-284</link>
		<dc:creator><![CDATA[Chung-chieh Shan]]></dc:creator>
		<pubDate>Fri, 19 Dec 2008 15:21:17 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=72#comment-284</guid>
		<description><![CDATA[&lt;p&gt;Very nice -- &quot;tidy and safe&quot; indeed!&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Very nice &#8212; &#8220;tidy and safe&#8221; indeed!</p>
]]></content:encoded>
	</item>
</channel>
</rss>
