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
|
||||
its cooperation, but threads currently all run on the same processor
|
||||
(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].
|
||||
In terms of the evaluation model, each step in evaluation
|
||||
actually deals with multiple concurrent
|
||||
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
|
||||
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
|
||||
imposed on all evaluation steps across threads). Most evaluation steps involve a
|
||||
single step in a single expression, but certain synchronization
|
||||
primitives require multiple threads to progress together in one step.
|
||||
single step in a single thread, but certain synchronization
|
||||
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
|
||||
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"
|
||||
#: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"
|
||||
#:title "An Object-Oriented Random-Number Package With Many Long Streams and Substreams"
|
||||
#:location "Operations Research, 50(6)"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
@guideintro["concurrency"]{threads}
|
||||
|
||||
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
|
||||
@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
|
||||
@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}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user