It seems that it&#39;s not the forkIO that is creating native threads (using GHC 6.10.1, -O flag)<div><div><br></div><div>For example, the following code only has 5 threads on my Windows box, while I fork 10 lightweight threads</div>
<div><br></div><div><div>import System.IO</div><div>import Control.Concurrent</div><div>import Control.Monad</div><div><br></div><div>entry :: Char -&gt; IO()</div><div>entry c  = do</div><div>  forever $ putChar c</div><div>
<span class="Apple-tab-span" style="white-space:pre">        </span></div><div>main = do</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>hSetBuffering stdout NoBuffering</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>mapM_ (forkIO . entry) [&#39;0&#39;..&#39;9&#39;]</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>putStrLn &quot;all forked; press ENTER to quit&quot;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>getLine</div><div><span class="Apple-tab-span" style="white-space:pre">        </span></div>
</div><div>However, things can get bizarre. When we change the entry function into</div><div><div><br></div><div>entry :: Char -&gt; IO()</div><div>entry c  = do</div><div>  putChar c</div><div>  threadDelay maxBound</div>
<div><br></div><div>Then on my machine 13 native threads *are* created. This might make sense because its waiting forever, but native threads are also created for the following code:</div><div><br></div><div><div>entry :: Char -&gt; IO()</div>
<div>entry c  = do</div><div>  putChar c</div><div>  forever $ threadDelay 0</div><div><br></div><div>This feels like overkill, so it seems threadDelay always forks a new native thread, although this is not documented.</div>
<div><br></div><div>We can also get into the dark corners of GHC&#39;s lightweight thread scheduling: a thread switch only happens when memory is allocated on the GC head (but this is documented in the API)</div><div><br>
</div><div>So the following code will not work, the runtime seems to get stuck in an infinite loop after the first thread is created.</div><div><br></div><div><div>entry :: Char -&gt; IO()</div><div>entry c  = do</div><div>
  putChar c</div><div>  forever $ return ()</div><div><br></div><div>In artificial cases like this you can use yield</div><div><br></div><div><div>entry :: Char -&gt; IO()</div><div>entry c  = do</div><div>  putChar c</div>
<div>  forever yield</div><div><br></div></div></div></div><div class="gmail_quote">On Mon, Apr 13, 2009 at 10:37 AM, Lych <span dir="ltr">&lt;<a href="mailto:lych77@gmail.com">lych77@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I wrote a simple ECHO server like this:<br>
----------------------------------------------------<br>
import Network<br>
import System.IO<br>
import Control.Concurrent<br>
<br>
service cs = do<br>
        ln &lt;- hGetContents cs<br>
        hPutStr cs ln<br>
        service cs<br>
<br>
<br>
acceptloop ls = do<br>
     (cs, host, port) &lt;- accept ls<br>
     hSetBuffering cs LineBuffering<br>
     forkIO (service cs)<br>
     acceptloop ls<br>
<br>
main = do<br>
     ls &lt;- listenOn (PortNumber 10061)<br>
     acceptloop ls<br>
----------------------------------------------------<br>
<br>
And tested it with a client that initiates as many parallel<br>
connections as possible. The number of connections can just reach to<br>
1000+ on my machine, but I thought it should be more, since forkIO<br>
generates lightweight threads. I also examined the number of threads<br>
in this process with some tool and it proved there was one native<br>
thread per connection. When I replaced the &#39;forkIO&#39; in the program<br>
with &#39;forkOS&#39;, I got an exactly similar result. Have I thought<br>
something wrong about forkIO?<br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
</blockquote></div><br></div></div>