Subato

Nebenläufigkeit in Haskell

.


> module Concurrent where > import Prelude hiding (putStr) > import Control.Concurrent > import Control.Concurrent.MVar > import Control.Parallel > import Control.Monad > import Data.List > import Data.String > import Control.Exception.Base > import Data.ByteString (putStr) > import Network.Socket > import System.IO hiding (putStr) > t1 = do > putStr$fromString "young" > t1 > t2 = forever$putStr$fromString "young" > t3 = do > forever$print "young" > putStr$fromString "fertig" > t4 = do > forever$ do > putStr$fromString "young" > threadDelay 1000000 > putStr$fromString "fertig" forkIO :: IO () -> IO ThreadId > t5 = do > forkIO$forever$ do > putStr$fromString "young" > threadDelay 1000000 > putStr$fromString "fertig" [1 of 1] Compiling Concurrent ( solution/Concurrent.lhs, interpreted ) Ok, one module loaded. *Concurrent> t5 youngfertig*Concurrent> youngyoungyoungyoungyoungyoung > t6 = do > forkIO$forever$ do > putStr$fromString "young" > threadDelay 1000000 > forkIO$forever$ do > putStr$fromString "forever" > threadDelay 1500000 > putStr$fromString "los gehts!" [1 of 1] Compiling Concurrent ( solution/Concurrent.lhs, interpreted ) Ok, one module loaded. *Concurrent> t6 los gehts!youngforever*Concurrent> youngforeveryoungforeveryoungyoungforeveryoung newEmptyMVar :: IO (MVar a) newMVar :: a -> IO (MVar a) > t7 = do > v <- newMVar 0 > forkIO$ rep v "A" 1000000 > rep v "B" 2000000 > rep v x delay = forever$ do > s <- takeMVar v > putMVar v (s+1) > print (x++show s) > threadDelay delay > needsTwo v1 v2 xs = do > _ <- takeMVar v1 > putStr$fromString xs > putStr$fromString ": I have one of the resources\n" > threadDelay 1000000 > _ <- takeMVar v2 > print xs > putMVar v1 () > putMVar v2 () > deadlock = do > v1 <- newMVar () > v2 <- newMVar () > forkIO$ needsTwo v1 v2 "eins" > needsTwo v2 v1 "zwei" panitz@px1:~/00021Concurrent$ ghci solution/Concurrent.lhs GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help [1 of 1] Compiling Concurrent ( solution/Concurrent.lhs, interpreted ) Ok, one module loaded. *Concurrent> deadlock eins: I have one of the resources zwei: I have one of the resources *** Exception: thread blocked indefinitely in an MVar operation *Concurrent> > fib n > |n<2 = n > |otherwise = fib (n-2)+fib (n-1) > tack function = do > v1 <- newEmptyMVar > forkIO (function v1) > putStr$fromString "Warte auf Fibonacci\n" > r <- (takeMVar v1)::IO Int > putStr$fromString "Variable mit Ergebnis ausgelesen\n" > putStr$fromString ("Ergebnis: ") > putStr$fromString$show r > putStr$fromString ("\nfertig!\n") > fib1 n v = do > putMVar v (fib n) > putStr$fromString "fib1 ist fertig\n" *Concurrent> tack$ fib1 35 Warte auf Fibonacci Variable mit Ergebnis ausgelesen Ergebnis: fib1 ist fertig 9227465 fertig! > fib2 n v = do > r <- evaluate$fib n > putMVar v r > putStr$fromString "fib2 ist fertig\n" *Concurrent> tack$ fib2 35 Warte auf Fibonacci fib2 ist fertig Variable mit Ergebnis ausgelesen Ergebnis: 9227465 fertig! > mvfib n > |n<=1 =return n > |otherwise = do > v1 <- newEmptyMVar > forkIO (fib2 (n-1) v1) > x2 <- evaluate$fib (n-2) > x1 <- takeMVar v1 > return (x1+x2) import System.Environment(getArgs) import Concurrent main = do (inp1:_) <- getArgs r<-mvfib $read inp1 print r 00021Concurrent$ ghc -threaded -rtsopts Concurrent.lhs MVFib.hs [1 of 2] Compiling Concurrent ( Concurrent.lhs, Concurrent.o ) [2 of 2] Compiling Main ( MVFib.hs, MVFib.o ) Linking MVFib ... 00021Concurrent$ time ./MVFib 42 fib2 ist fertig 267914296 real 0m43,364s user 0m43,277s sys 0m0,076s 00021Concurrent$ time ./MVFib 42 +RTS -N2 fib2 ist fertig 267914296 real 0m34,895s user 0m55,897s sys 0m0,859s > pfib d n > |n<=1 = n > |d<=0 = fib n > |otherwise > = let > x1 = fib (n-2) > x2 = pfib (d-1) (n-1) > in x1 `par` x2 `pseq` x1+x2 import System.Environment(getArgs) import Concurrent main = do (inp1:d:_) <- getArgs print$pfib (read d)$read inp1 00021Concurrent$ time ./PFib 42 4 267914296 real 0m46,114s user 0m46,057s sys 0m0,104s 00021Concurrent$ time ./PFib 42 4 +RTS -N4 267914296 real 0m30,792s user 1m28,086s sys 0m1,795s > chanT = do > c1 <- newChan > c2 <- dupChan c1 > forkIO$readFrom "eins" c1 > forkIO$readFrom "zwei" c2 > writeTo 1 c1 > readFrom name c = forever$do > n <- readChan c > putStr$fromString (name++": "++show n++"\n") > writeTo n c = do > writeChan c n > threadDelay 1000000 > writeTo (n+1) c *Concurrent> chanT zwei: 1 eins: 1 eins: 2 zwei: 2 > startChatServer = do > sock <- socket AF_INET Stream defaultProtocol > bind sock (SockAddrInet 4242 (tupleToHostAddress (127,0,0,1))) > listen sock 2 > chan <- newChan > forever$ do > con <- accept sock > forkIO (verbindung con chan) > verbindung (sock, _) chan = do > hdl <- socketToHandle sock ReadWriteMode > hPutStrLn hdl "Bitte einen Chatnamen eingeben?" > name <- hGetLine hdl > writeChan chan ("> " ++ (init name) ++ " ist neu imm Chat.") > commLine <- dupChan chan > forkIO $ forever$ do > line <- readChan commLine > hPutStrLn hdl line > forever$ do > line <- hGetLine hdl > writeChan chan ((init name) ++ ": " ++ line) 00021Concurrent$ ghci solution/Concurrent.lhs GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help [1 of 1] Compiling Concurrent ( solution/Concurrent.lhs, interpreted ) Ok, one module loaded. *Concurrent> startChatServer panitz@px1:~$ telnet localhost 4242 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Bitte einen Chatnamen eingeben? Bernd --> Klaus ist neu imm Chat. hallo Klaus Bernd: hallo Klaus Klaus: Hallo Bernd panitz@px1:~$ telnet localhost 4242 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Bitte einen Chatnamen eingeben? Klaus Bernd: hallo Klaus Hallo Bernd Klaus: Hallo Bernd
lhs
You are not logged in and therefore you cannot submit a solution.