Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
GHC
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Gesh
GHC
Commits
be205c35
Commit
be205c35
authored
25 years ago
by
Simon Peyton Jones
Browse files
Options
Downloads
Patches
Plain Diff
[project @ 1999-08-31 08:49:00 by simonpj]
Small changes to concurrency documentation
parent
b07b68d3
Loading
Loading
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
ghc/docs/libraries/Concurrent.sgml
+56
-51
56 additions, 51 deletions
ghc/docs/libraries/Concurrent.sgml
with
56 additions
and
51 deletions
ghc/docs/libraries/Concurrent.sgml
+
56
−
51
View file @
be205c35
...
...
@@ -82,6 +82,24 @@ thread itself. This means the thread itself can't be garbage
collected until you drop the <tt/ThreadId/. This misfeature will
hopefully be corrected at a later date.
<sect1> Scheduling
<p>
GHC uses <em>preemptive multitasking</em>: context switches can occur
at any time. At present, Hugs uses <em>cooperative multitasking</em>:
context switches only occur when you use one of the primitives defined
in this module. This means that programs such as:
<tscreen><verb>
main = forkIO (write 'a') >> write 'b'
where write c = putChar c >> write c
</verb></tscreen>
will print either <tt/aaaaaaaaaaaaaa.../ or <tt/bbbbbbbbbbbb.../,
instead of some random interleaving of <tt/a/s and <tt/b/s.
In practice, cooperative multitasking is sufficient for writing simple
graphical user interfaces.
The <tt>yield</tt> action forces a context-switch to any other
currently runnable threads (if any), and is occasionally useful when
implementing concurrency abstractions:
...
...
@@ -90,6 +108,39 @@ implementing concurrency abstractions:
yield :: IO ()
</verb></tscreen>
<sect2> <idx/Thread Waiting/
<p>
Finally, there are operations to delay a concurrent thread, and to
make one wait:<nidx>delay a concurrent thread</nidx>
<nidx>wait for a file descriptor</nidx>
<tscreen><verb>
threadDelay :: Int -> IO () -- delay rescheduling for N microseconds
threadWaitRead :: Int -> IO () -- wait for input on specified file descriptor
threadWaitWrite :: Int -> IO () -- (read and write, respectively).
</verb></tscreen>
The <tt/threadDelay/ operation will cause the current thread to
suspend for a given number of microseconds. Note that the resolution
used by the Haskell runtime system's internal timer together with the
fact that the thread may take some time to be rescheduled after the
time has expired, means that the accuracy is more like 1/50 second.
<tt/threadWaitRead/ and <tt/threadWaitWrite/ can be used to block a
thread until I/O is available on a given file descriptor. These
primitives are used by the I/O subsystem to ensure that a thread
waiting on I/O doesn't hang the entire system.
<sect2> <idx/Blocking/
<p>
Calling a foreign C procedure (such as <tt/getchar/) that blocks
waiting for input will block <em>all</em> threads, in both
GHC and Hugs. The GHC I/O system uses non-blocking I/O internally to implement
thread-friendly I/O, so calling standard Haskell I/O functions blocks
only the thead making the call.
<sect1> <idx/Concurrency abstractions/
<label id="sec:Concurrency-abstractions">
<p>
...
...
@@ -137,7 +188,7 @@ time a thread gets to inspect the result and act upon it, other
threads may have accessed the <tt/MVar/ and changed the 'filled-in'
status of the variable.
The same proviso applies to <tt/isEmptyChan/.
The same proviso applies to <tt/isEmptyChan/
(next sub-section)
.
These two predicates are currently only supported by GHC.
...
...
@@ -200,6 +251,9 @@ mergeIO :: [a] -> [a] -> IO [a]
nmergeIO :: [[a]] -> IO [a]
</verb></tscreen>
These actions fork one thread for each input list that concurrently
evaluates that list; the results are merged into a single output list.
Note: Hugs does not provide the functions <tt/mergeIO/ or
<tt/nmergeIO/ since these require preemptive multitasking.
...
...
@@ -230,32 +284,7 @@ readSample :: SampleVar a -> IO a
writeSample :: SampleVar a -> a -> IO ()
</verb></tscreen>
<sect2> <idx/Thread Waiting/
<label id="sec:Channels">
<p>
Finally, there are operations to delay a concurrent thread, and to
make one wait:<nidx>delay a concurrent thread</nidx>
<nidx>wait for a file descriptor</nidx>
<tscreen><verb>
threadDelay :: Int -> IO () -- delay rescheduling for N microseconds
threadWaitRead :: Int -> IO () -- wait for input on specified file descriptor
threadWaitWrite :: Int -> IO () -- (read and write, respectively).
</verb></tscreen>
The <tt/threadDelay/ operation will cause the current thread to
suspend for a given number of microseconds. Note that the resolution
used by the Haskell runtime system's internal timer together with the
fact that the thread may take some time to be rescheduled after the
time has expired, means that the accuracy is more like 1/50 second.
<tt/threadWaitRead/ and <tt/threadWaitWrite/ can be used to block a
thread until I/O is available on a given file descriptor. These
primitives are used by the I/O subsystem to ensure that a thread
waiting on I/O doesn't hang the entire system.
<sect2> The <tt/Concurrent/ library interface
<sect1> The <tt/Concurrent/ library interface
<p>
The full interface for the <tt/Concurrent/ library is given below for
...
...
@@ -321,30 +350,6 @@ threadWaitRead :: Int -> IO ()
threadWaitWrite :: Int -> IO ()
</verb></tscreen>
<sect1> Pre-emptive vs. Cooperative multitasking
<p>
GHC uses preemptive multitasking: Context switches can occur at any
time, except if you call a C function (like <tt/getchar/) that blocks
waiting for input. Haskell I/O is unaffected by blocking operations
(the GHC I/O system uses non-blocking I/O internally to implement
thread-friendly I/O).
Hugs uses cooperative multitasking: Context switches only occur when
you use one of the primitives defined in this module. This means that
programs such as:
<tscreen><verb>
main = forkIO (write 'a') >> write 'b'
where write c = putChar c >> write c
</verb></tscreen>
will print either <tt/aaaaaaaaaaaaaa.../ or <tt/bbbbbbbbbbbb.../,
instead of some random interleaving of <tt/a/s and <tt/b/s.
In practice, cooperative multitasking is sufficient for writing simple
graphical user interfaces.
<sect1> GHC-specific concurrency issues
<p>
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment