I am running my program in WinXP with ghc 2.6.8<br><br>If you install netstat and change the parameters it should still work in linux.<br><br><br>Why does thread # 3 dominate over the over threads int the output?<br>Why does thread # 4 never seem to run?<br>
<br>I can't use the sleep function in System.Process.Win32 since it puts all the <br>threads asleep at the same time. Is there a way to put only one thread asleep?<br><br>That would allow more of a chance for thread #4 to run.<br>
<br><br><br>The simplified program:<br>---------------------------------------------------------------<br><br><br>module Main where<br><br>import Data.IORef<br>import Data.List<br>import System.IO<br>import System.Process<br>
<br>import Control.Concurrent<br>import Control.Concurrent.Chan<br><br><br>data Connection = Null | Last | Active deriving (Eq)<br><br>instance Show Connection where<br> show Null = "Null"<br> show Last = "Last"<br>
show Active = "Active"<br><br>instance Read Connection where<br>readsPrec _ s = case take 5 s of<br> " UDP" -> [(Active, "")]<br> " TCP" -> [(Active, "")]<br>
"Last" -> [(Last,"")]<br> _ -> [(Null,"")]<br><br><br>-- ptrints one 0 and 1<br>main = do<br> stop <- newIORef False<br> cbuffer <- newChan :: IO (Chan Connection)<br>
putStr "0"<br> (_,output,_,ph) <- runInteractiveCommand "netstat -noa 5"<br> sequence $ map forkIO $ [(processConnections ph output cbuffer), (stopNetstat ph stop False), (printChan cbuffer),(checkStop stop "xxxx")]<br>
putStr "1"<br> _ <- waitForProcess ph<br> --mapM killThread ts<br> putStrLn "\nDone"<br><br>-- thread # 2<br>processConnections :: ProcessHandle -> Handle -> (Chan Connection) -> IO ()<br>
processConnections ph hout chan = do<br> h <- hReady hout<br> e <- getProcessExitCode ph<br>putStr "2"<br> if (not h && e /= Nothing) then do writeChan chan Last >> return () else do<br> if h then do readConnection hout >>= writeChan chan else do<br>
processConnections ph hout chan<br><br> <br>readConnection :: Handle -> IO Connection<br>readConnection hout = do<br> l <- hGetLine hout<br> let c = (read l :: Connection)<br> if (c == Null) <br> then do (readConnection hout)<br>
else do (return c)<br><br>-- thread number 3<br>stopNetstat :: ProcessHandle -> (IORef Bool) -> Bool -> IO ()<br>stopNetstat netstat _ True = terminateProcess netstat<br>stopNetstat netstat gref False = putStr "3" >> yield >> readIORef gref >>= stopNetstat netstat gref<br>
<br><br>--thread 4<br>printChan :: (Chan Connection) -> IO () <br>printChan chan = do<br>putStr "4"<br> c <- readChan chan<br>printConnection c<br>printChan chan<br><br><br>checkStop :: (IORef Bool) -> String -> IO ()<br>
checkStop ref s = do<br> if (take 4 s == "stop") <br> then do (writeIORef ref True) <br> else do (getChar >>= (\x -> checkStop ref ((tail s) ++ [x])))<br><br>printConnection :: Connection -> IO ()<br>
printConnection c = case c of<br> Null -> putStr "N" <br> Last -> putStr "L"<br> _ -> putStr "A"<br><br>