11.2.4 Buffered Asynchronous Channels

► |  | The Racket Reference

1 | Language Model
2 | Notation for Documentation
3 | Syntactic Forms
4 | Datatypes
5 | Structures
6 | Classes and Objects
7 | Units
8 | Contracts
9 | Pattern Matching
10 | Control Flow
11 | Concurrency and Parallelism
12 | Macros
13 | Input and Output
14 | Reflection and Security
15 | Operating System
16 | Memory Management
17 | Unsafe Operations
18 | Running Racket
| Bibliography
| Index

► | 11 | Concurrency and Parallelism

11.1 | Threads
11.2 | Synchronization
11.3 | Thread-Local Storage
11.4 | Futures
11.5 | Places
11.6 | Engines

▼ | 11.2 | Synchronization

11.2.1 | Events
11.2.2 | Channels
11.2.3 | Semaphores
11.2.4 | Buffered Asynchronous Channels

► | 11.2.4 | Buffered Asynchronous Channels

11.2.4.1 | Creating and Using Asynchronous Channels
11.2.4.2 | Contracts and Impersonators on Asynchronous Channels

On this page:

11.2.4.1`` Creating and Using Asynchronous Channels
async-channel?
make-async-channel
async-channel-get
async-channel-try-get
async-channel-put
async-channel-put-evt
11.2.4.2`` Contracts and Impersonators on Asynchronous Channels
async-channel/ c
impersonate-async-channel
chaperone-async-channel

top ← prev up next →

##### 11.2.4`` Buffered Asynchronous Channels

(require racket/async-channel) | package: base

The bindings documented in this section are provided by the racket/async-channel library, not racket/base or racket.

##### 11.2.4.1`` Creating and Using Asynchronous Channels

> > > See also Thread Mailboxes.

An asynchronous channel is like a channel, but it buffers values so that a send operation does not wait on a receive operation.

In addition to its use with procedures that are specific to asynchronous channels, an asynchronous channel can be used as a synchronizable event (see Events). An asynchronous channel is ready for synchronization when async-channel-get would not block; the asynchronous channel’s synchronization result is the same as the async-channel-get result.

> procedure (async-channel? v) → boolean?
> v : any/c

Returns #t if v is an asynchronous channel, #f otherwise.

> procedure (make-async-channel [limit]) → async-channel?
> limit : (or/c exact-positive-integer? #f) = #f

Returns an asynchronous channel with a buffer limit of limit items. A get operation blocks when the channel is empty, and a put operation blocks when the channel has limit items already. If limit is #f, the channel buffer has no limit (so a put never blocks).

> procedure (async-channel-get ach) → any/c
> ach : async-channel?

Blocks until at least one value is available in ach, and then returns the first of the values that were put into async-channel.

> procedure (async-channel-try-get ach) → any/c
> ach : async-channel?

If at least one value is immediately available in ach, returns the first of the values that were put into ach. If async-channel is empty, the result is #f.

> procedure (async-channel-put ach v) → void?
> ach : async-channel?
> v : any/c

Puts v into ach, blocking if ach’s buffer is full until space is available.

> procedure (async-channel-put-evt ach v) → evt?
> ach : async-channel?
> v : any/c

Returns a synchronizable event that is ready for synchronization when (async-channel-put ach v) would return a value (i.e., when the channel holds fewer values already than its limit); the synchronization result of a asychronous channel-put event is the asychronous channel-put event itself.

Examples:

> (define (server input-channel output-channel)
> (thread (lambda ()
> (define (get)
> (async-channel-get input-channel))
> (define (put x)
> (async-channel-put output-channel x))
> (define (do-large-computation)
> (sqrt 9))
> (let loop ([data (get)])
> (case data
> [(quit) (void)]
> [(add) (begin
> (put (+ 1 (get)))
> (loop (get)))]
> [(long) (begin
> (put (do-large-computation))
> (loop (get)))])))))
> (define to-server (make-async-channel))
> (define from-server (make-async-channel))
> > (server to-server from-server)
> #<thread>
> > (async-channel? to-server)
> #t
> > (printf "Adding 1 to 4\n")
> Adding 1 to 4
> > (async-channel-put to-server 'add)
> > (async-channel-put to-server 4)
> > (printf "Result is ~a\n" (async-channel-get from-server))
> Result is 5
> > (printf "Ask server to do a long computation\n")
> Ask server to do a long computation
> > (async-channel-put to-server 'long)
> > (printf "I can do other stuff\n")
> I can do other stuff
> > (printf "Ok, computation from server is ~a\n"
> (async-channel-get from-server))
> Ok, computation from server is 3
> > (async-channel-put to-server 'quit)

##### 11.2.4.2`` Contracts and Impersonators on Asynchronous Channels

> procedure (async-channel/c c) → contract?
> c : contract?

Returns a contract that recognizes asynchronous channels. Values put into or retrieved from the channel must match c.

If the c argument is a flat contract or a chaperone contract, then the result will be a chaperone contract. Otherwise, the result will be an impersonator contract.

When an async-channel/c contract is applied to an asynchronous channel, the result is not eq? to the input. The result will be either a chaperone or impersonator of the input depending on the type of contract.

> > procedure
> > (impersonate-async-channel |  | channel |
> > |  | get-proc |
> > |  | put-proc |
> > |  | prop |
> > |  | prop-val ... |
> > |  | ...) |
> → (and/c async-channel? impersonator?)
> channel : async-channel?
> get-proc : (any/c . -> . any/c)
> put-proc : (any/c . -> . any/c)
> prop : impersonator-property?
> prop-val : any

Returns an impersonator of channel, which redirects the async-channel-get and async-channel-put operations.

The get-proc must accept the value that async-channel-get produces on channel; it must produce a replacement value, which is the result of the get operation on the impersonator.

The put-proc must accept the value passed to async-channel-put called on channel; it must produce a replacement value, which is the value passed to the put procedure called on the original channel.

The get-proc and put-proc procedures are called for all operations that get or put values from the channel, not just async-channel-get and async-channel-put.

Pairs of prop and prop-val (the number of arguments to impersonate-async-channel must be odd) add impersonator properties or override impersonator property values of channel.

> > procedure
> > (chaperone-async-channel |  | channel |
> > |  | get-proc |
> > |  | put-proc |
> > |  | prop |
> > |  | prop-val ... |
> > |  | ...) |
> → (and/c async-channel? chaperone?)
> channel : async-channel?
> get-proc : (any/c . -> . any/c)
> put-proc : (any/c . -> . any/c)
> prop : impersonator-property?
> prop-val : any

Like impersonate-async-channel, but the get-proc procedure must produce the same value or a chaperone of the original value, and put-proc must produce the same value or a chaperone of the original value.
top ← prev up next →