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