[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