[Haskell-cafe] Concurrency question
Donald Bruce Stewart
dons at cse.unsw.edu.au
Sun Sep 4 03:30:18 EDT 2005
akamaus:
> Hi, everyone!
>
> I have a function, which sometimes takes a long time to compute or even
> may loop forever. So I want to limit it in time somehow.
>
> I tried to run it in another thread in order to kill it after its time
> lapsed. But it seems to lock out other threads so they can't terminate it.
>
> I wonder is there some clever way of dealing with such situation
> (running a computation in background for specific time) ?
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. This is pretty much bullet proof:
> import System.Exit
> import System.Posix.Resource
>
> rlimit = ResourceLimit 3 -- 3 second time limit
>
> main = do
> setResourceLimit ResourceCPUTime (ResourceLimits rlimit rlimit)
> ... run my dangerous loop ...
> exitWith ExitSuccess
And then in the host application:
> (out,err,_) <- popen "my_loop_code" [] Nothing
> return $ case () of {_
> | null out && null err -> "Terminated\n"
> | null out -> err
> | otherwise -> out
> }
where popen looks something like:
> popen :: FilePath -> [String] -> Maybe String -> IO (String,String,ProcessID)
> popen file args minput =
> Control.Exception.handle (\e -> return ([],show e,error (show e))) $ do
> (inp,out,err,pid) <- runInteractiveProcess file args Nothing Nothing
> case minput of
> Just input -> hPutStr inp input >> hClose inp
> Nothing -> return ()
> output <- hGetContents out
> errput <- hGetContents err
> forkIO (Control.Exception.evaluate (length output) >> return ())
> forkIO (Control.Exception.evaluate (length errput) >> return ())
> waitForProcess pid -- blocks without -threaded, you're warned.
> return (output,errput,pid)
Cheers,
Don
More information about the Haskell-Cafe
mailing list