[Haskell-cafe] Concurrency question
Dmitry Vyal
akamaus at gmail.com
Sun Sep 4 13:45:37 EDT 2005
Donald Bruce Stewart wrote:
> Maybe your loop does no allocations, so the scheduler can't get in and do a
> context switch. You could put the computation in an external program, and run
> it over a fork, using unix signals in the external program to kill the
> computation after a period of time.
I thought about doing that, but function is closely connected with the
rest of the program. Running it in another process would require some
parsing of its arguments and I want circumvent these difficulties.
Moreover, this function indeed allocates plenty of memory (creates long
lists), so It's just curiously for me to establish the reason of this
(mis)behavior. By the way, what does it mean precisely, "no allocations".
This is the top part of program I have trouble with. "resolve" is that
sluggish function, which execution I'm trying to break. It hogs a lot of
memory, so context switching should occur regular.
I'm new to Haskell, so probably I've just made some really stupid mistake.
Thanks a lot for your help.
res_timeout=1000000 -- time quota in microseconds
forever a = a >> forever a
main :: IO ()
main = do args <- getArgs
if (length args /= 1) then usage
else do axioms <- readFile (head args)
let tree = parseInput axioms
case tree of
(Right exprs) ->
do let cnf = normalize $
concatMap to_cnf exprs
forever $ one_cycle cnf
(Left er) -> putStr $ show er
usage = putStr "usage: resolution <filename>\n"
one_cycle :: CNF -> IO ()
one_cycle base =
do inp <- getLine
let lex_tree = parseInput inp
case lex_tree of
(Right exprs) -> run_resolution $
normalize $ to_cnf (Not (head exprs))
++ base
(Left er) -> putStr $ show er
-- Here I start a heavy computation
run_resolution :: CNF -> IO ()
run_resolution cnf =
do res <- timeout res_timeout (return $ resolve cnf)
case res of
Just (ans, stats) -> do print stats
print ans
Nothing -> print "***timeout***"
-- These useful subroutines I saw in "Tackling The Awkward Squad"
par_io :: IO a -> IO a -> IO a
par_io t1 t2 = do c <- newEmptyMVar :: IO (MVar a)
id1 <- forkIO $ wrapper c t1
id2 <- forkIO $ wrapper c t2
res <- takeMVar c
killThread id1
killThread id2
return res
where wrapper :: MVar a -> IO a -> IO ()
wrapper mvar io = do res <- io
putMVar mvar res
timeout :: Int -> IO a -> IO (Maybe a)
timeout n t = do res <- par_io timer thr
return res
where thr = do res <- t
return $ Just res
timer = do threadDelay n
return Nothing
More information about the Haskell-Cafe
mailing list