[Haskell-cafe] Concurrency question
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) ? Thanks a lot. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Concurrency question
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 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] [beta] cabal-get: install haskell packages automatically
Beta testers wanted! Lemmih (mostly) has been working on a tool which will download and install Haskell packages and their dependencies. This tool should work for any cabal-compatible package. We're looking for beta testers to try out cabal-get (for downloading and installing) and cabal-put (for uploading to the central repository). We're also looking for more developers to work on this. The home, for now is here: http://hackage.haskell.org/ModHackage/Hackage.hs?action=home and to get cabal-get, grab the bootstrapper: darcs get http://hackage.haskell.org/darcs/cabal-get-bootstrap And execute the Install.lhs file. You may have to modify it slightly if you don't like the defaults. After you install cabal-get, you should be able to install cabal-put by saying: cabal-get update cabal-get install cabal-put Darcs repositories for all the tools are here: http://hackage.haskell.org/darcs/ Questions or problems? Email me or Lemmih. peace, isaac ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] A better, fair, and terminating backtracking monad [Was: Concurrency question]
Dmitry Vyal wrote: Currently I'm playing with theorem-proving using resolution. So I need some technique to break a computation, if takes too long. When it comes to resolution proofs, perhaps a better approach is to use a better monad that natively offers termination guarantees. For example, http://pobox.com/~oleg/ftp/Computation/monads.html#fair-bt-stream First of all, the monad can let succeed the computations that surely diverge in List and similar monads. As the code at the end of that file shows, the monad avoids depth-first traps, and can even handle left-recursion at the monadic level. Furthermore, the monad has the inherent `timing' metric: Incomplete eliminations. Each elimination is bounded in time. One can specify the upper bound on the number of eliminations and thus force the termination if no solution was found thus far. It is possible to modify the run function of the monad to return the continuation once the counter has expired. So, one can run the monad for a bit more, if desired. In contrast to iterative deepening, running the continuation does _not_ repeat any of the previous work. We have used the FBackTrack monad to implement a Datalog-like system (with top-down. resolution-based search however), and we could successfully solve the problem of finding the transitive closure in a _cyclic_ graph (the poster problem for post-Prolog systems like XSB). No tabling was needed. A scheme version of the monad was used in a leanTAP theorem prover (for the full first-order predicate logic): http://cvs.sourceforge.net/viewcvs.py/kanren/kanren/mini/leanTAP.scm http://cvs.sourceforge.net/viewcvs.py/kanren/kanren/mini/book-si.scm The original leanTAP prover was meant to be used with iterative deepening. Our implementation removes the limiting counter from the leanTAP (which throttles instantiations of a universally quantified formula); the monad has enough strength to find the solution anyway (Pelletier problems 43 and 38). ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Concurrency question
akamaus: 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. Ah, I've found another example. This function attempts to run an expensive computation. If it doesn't return within a given time, a cheap function is used instead. This was mostly written by Stefan Wehr: watchdogIO :: Int -- milliseconds - IO a -- expensive computation - IO a -- cheap computation - IO a watchdogIO millis expensive cheap = do mvar - newEmptyMVar tid1 - forkIO $ do x - expensive x `seq` putMVar mvar (Just x) tid2 - forkIO $ do threadDelay (millis * 1000) putMVar mvar Nothing res - takeMVar mvar case res of Just x - do info (EXPENSIVE was used) killThread tid2 `catch` (\e - warn (show e)) return x Nothing - do info (WATCHDOG after ++ show millis ++ milliseconds) killThread tid1 `catch` (\e - warn (show e)) cheap -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe