Talk:Parallelism vs. Concurrency
Parallelism vs concurrency: what's the difference?
Visible side effects.
- Have a look at this
ugly eysore"prototype definition" of
par :: a -> b -> b par x y = case unsafeLocalState (forkIO (evaluate x >> return ())) of !_ -> y
evaluate :: a -> IO a forkIO :: IO () -> IO ThreadId
xis well-defined (it contains no
xis well-behaved (not throwing exceptions or causing errors);
ThreadIdto its argument, adds it to the work-queue and returns the identifier;
- Some time later,
forkIO's argument is called, causing
evaluateto start evaluating
yis still being evaluated when the evaluation of
xcommences, then we have concurrency, but with no visible side-effects - elementary parallelism.
- Now have a look at this
nearly-as-uglyprototype definition for
forkIO :: IO () -> IO ThreadId forkIO act = do t <- unsafeInterleaveIO act case attachThreadId t of Nothing -> itsThreadId t Just i -> par t (return i)
attachThreadId :: a -> IO (Maybe ThreadId) itsThreadId :: a -> IO ThreadId
Nothingif it's argument already has been assigned a
- A new
ThreadIdis assigned to the new (and suspended) value
par t icauses
tto be added to the work-queue by the implementation;
tis then returned;
- Some time later, the implementation discovers that a
ThreadIdhas been attached to
tand uses the
ThreadIdto immediately start a new thread for evaluating
This is parallelism, but having visible side effects - it looks very much like elementary concurrency.
Can either of these prototypes ever go mainstream?
- As shown by it's type signature,
paris supposed to be pure: avoiding the use of
unsafeLocalStatemeans making it primitive;
- While the use of
unsafeInterleaveIOmay annoy some, it being one of the earlier Haskell extensions means it's widely available.
For now, using a primitive
par (and others) to define
forkIO looks like the simplest option...but if using
unsafeInterleaveIO really does annoy you, how about this:
forkIO :: (OI -> ()) -> OI -> ThreadId forkIO act u = let !(u1:u2:u3:_) = parts u in let t = act u1 in case attachThreadId t u2 of Nothing -> itsThreadId t u3 Just i -> par t i
-- Atravers Tue Apr 20 06:04:10 UTC 2021