reference: improve description of thread-based concurrency
Related to #2834
This commit is contained in:
parent
a07e973316
commit
10b110adc1
|
@ -953,18 +953,42 @@ Racket supports multiple @deftech{threads} of evaluation. Threads run
|
||||||
concurrently, in the sense that one thread can preempt another without
|
concurrently, in the sense that one thread can preempt another without
|
||||||
its cooperation, but threads currently all run on the same processor
|
its cooperation, but threads currently all run on the same processor
|
||||||
(i.e., the same underlying operating system process and thread). See also
|
(i.e., the same underlying operating system process and thread). See also
|
||||||
@secref["futures"].
|
@secref["futures"] and @secref["places"].
|
||||||
|
|
||||||
Threads are created explicitly by functions such as @racket[thread].
|
Threads are created explicitly by functions such as @racket[thread].
|
||||||
In terms of the evaluation model, each step in evaluation
|
In terms of the evaluation model, each step in evaluation
|
||||||
actually deals with multiple concurrent
|
actually deals with multiple concurrent
|
||||||
expressions, up to one per thread, rather than a single expression. The expressions all
|
expressions, up to one per thread, rather than a single expression. The expressions all
|
||||||
share the same objects and top-level variables, so that they can
|
share the same objects and top-level variables, so that they can
|
||||||
communicate through shared state, and sequential consistency is
|
communicate through shared state, and @defterm{sequential consistency} @cite["Lamport79"] is
|
||||||
guaranteed (i.e., the result is consistent with some global sequence
|
guaranteed (i.e., the result is consistent with some global sequence
|
||||||
imposed on all evaluation steps across threads). Most evaluation steps involve a
|
imposed on all evaluation steps across threads). Most evaluation steps involve a
|
||||||
single step in a single expression, but certain synchronization
|
single step in a single thread, but certain synchronization
|
||||||
primitives require multiple threads to progress together in one step.
|
primitives require multiple threads to progress together in one step; for example,
|
||||||
|
an exchange of a value through a @tech{channel} progresses in two
|
||||||
|
threads simultaneously.
|
||||||
|
|
||||||
|
Unless otherwise noted, all constant-time procedures and operations
|
||||||
|
provided by Racket are thread-safe in the sense that they are
|
||||||
|
@defterm{atomic}: they happen as a single evaluation step.
|
||||||
|
For example, @racket[set!] assigns to a variable as an atomic action
|
||||||
|
with respect to all threads, so that no thread can see a
|
||||||
|
``half-assigned'' variable. Similarly, @racket[vector-set!] assigns to
|
||||||
|
a vector atomically. Note that the evaluation of a @racket[set!]
|
||||||
|
expression with its subexpression is not necessarily atomic, because
|
||||||
|
evaluating the subexpression involves a separate step of evaluation.
|
||||||
|
Only the assignment action itself (which takes after the subexpression
|
||||||
|
is evaluated to obtain a value) is atomic. Similarly, a procedure
|
||||||
|
application can involve multiple steps that are not atomic, even if
|
||||||
|
the procedure itself performs an atomic action.
|
||||||
|
|
||||||
|
The @racket[hash-set!] procedure is not atomic, but the table is
|
||||||
|
protected by a lock; see @secref["hashtables"] for more information.
|
||||||
|
Port operations are generally not atomic, but they are thread-safe in
|
||||||
|
the sense that a byte consumed by one thread from an input port will
|
||||||
|
not be returned also to another thread, and procedures like
|
||||||
|
@racket[port-commit-peeked] and @racket[write-bytes-avail] offer
|
||||||
|
specific concurrency guarantees.
|
||||||
|
|
||||||
In addition to the state that is shared among all threads, each thread
|
In addition to the state that is shared among all threads, each thread
|
||||||
has its own private state that is accessed through @deftech{thread
|
has its own private state that is accessed through @deftech{thread
|
||||||
|
|
|
@ -168,7 +168,13 @@ The @racketmodname[racket] library combines
|
||||||
#:location "Principles and Practice of Parallel Programming"
|
#:location "Principles and Practice of Parallel Programming"
|
||||||
#:date "1990")
|
#:date "1990")
|
||||||
|
|
||||||
(bib-entry #:key "L'Ecuyer02"
|
(bib-entry #:key "Lamport79"
|
||||||
|
#:title "How to Make a Multiprocessor Computer That Correctly Executes Multiprocess Programs"
|
||||||
|
#:author "Leslie Lamport"
|
||||||
|
#:location "IEEE Transactions on Computers"
|
||||||
|
#:date "179")
|
||||||
|
|
||||||
|
(bib-entry #:key "L'Ecuyer02"
|
||||||
#:author "Pierre L'Ecuyer, Richard Simard, E. Jack Chen, and W. David Kelton"
|
#:author "Pierre L'Ecuyer, Richard Simard, E. Jack Chen, and W. David Kelton"
|
||||||
#:title "An Object-Oriented Random-Number Package With Many Long Streams and Substreams"
|
#:title "An Object-Oriented Random-Number Package With Many Long Streams and Substreams"
|
||||||
#:location "Operations Research, 50(6)"
|
#:location "Operations Research, 50(6)"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
@guideintro["concurrency"]{threads}
|
@guideintro["concurrency"]{threads}
|
||||||
|
|
||||||
See @secref["thread-model"] for basic information on the Racket
|
See @secref["thread-model"] for basic information on the Racket
|
||||||
thread model. See also @secref["futures"].
|
thread model. See also @secref["futures"] and @secref["places"].
|
||||||
|
|
||||||
When a thread is created, it is placed into the management of the
|
When a thread is created, it is placed into the management of the
|
||||||
@tech{current custodian} and added to the current @tech{thread
|
@tech{current custodian} and added to the current @tech{thread
|
||||||
|
@ -31,19 +31,6 @@ A thread can be used as a @tech{synchronizable event} (see
|
||||||
@secref["sync"]). A thread is @tech{ready for synchronization} when
|
@secref["sync"]). A thread is @tech{ready for synchronization} when
|
||||||
@racket[thread-wait] would not block; @resultItself{thread}.
|
@racket[thread-wait] would not block; @resultItself{thread}.
|
||||||
|
|
||||||
All constant-time procedures and operations provided by Racket are
|
|
||||||
thread-safe because they are @defterm{atomic}. For example,
|
|
||||||
@racket[set!] assigns to a variable as an atomic action with respect
|
|
||||||
to all threads, so that no thread can see a ``half-assigned''
|
|
||||||
variable. Similarly, @racket[vector-set!] assigns to a vector
|
|
||||||
atomically. The @racket[hash-set!] procedure is not atomic, but
|
|
||||||
the table is protected by a lock; see @secref["hashtables"] for more
|
|
||||||
information. Port operations are generally not atomic, but they are
|
|
||||||
thread-safe in the sense that a byte consumed by one thread from an
|
|
||||||
input port will not be returned also to another thread, and procedures
|
|
||||||
like @racket[port-commit-peeked] and @racket[write-bytes-avail] offer
|
|
||||||
specific concurrency guarantees.
|
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section{Creating Threads}
|
@section{Creating Threads}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user