11.2.3 Semaphores

► |  | 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

On this page:

semaphore?
make-semaphore
semaphore-post
semaphore-wait
semaphore-try-wait?
semaphore-wait/ enable-break
semaphore-peek-evt
semaphore-peek-evt?
call-with-semaphore
call-with-semaphore/ enable-break

top ← prev up next →

##### 11.2.3`` Semaphores

A semaphore has an internal counter; when this counter is zero, the semaphore can block a thread’s execution (through semaphore-wait) until another thread increments the counter (using semaphore-post). The maximum value for a semaphore’s internal counter is platform-specific, but always at least 10000.

A semaphore’s counter is updated in a single-threaded manner, so that semaphores can be used for reliable synchronization. Semaphore waiting is fair: if a thread is blocked on a semaphore and the semaphore’s internal value is non-zero infinitely often, then the thread is eventually unblocked.

In addition to its use with semaphore-specific procedures, a semaphore can be used as a synchronizable event (see Events). A semaphore is ready for synchronization when semaphore-wait would not block; the synchronization result of a semaphore is the semaphore itself.

> procedure (semaphore? v) → boolean?
> v : any/c

Returns #t if v is a semaphore, #f otherwise.

> procedure (make-semaphore [init]) → semaphore?
> init : exact-nonnegative-integer? = 0

Creates and returns a new semaphore with the counter initially set to init. If init is larger than a semaphore’s maximum internal counter value, the exn:fail exception is raised.

> procedure (semaphore-post sema) → void?
> sema : semaphore?

Increments the semaphore’s internal counter and returns #<void>. If the semaphore’s internal counter has already reached its maximum value, the exn:fail exception is raised.

> procedure (semaphore-wait sema) → void?
> sema : semaphore?

Blocks until the internal counter for semaphore sema is non-zero. When the counter is non-zero, it is decremented and semaphore-wait returns #<void>.

> procedure (semaphore-try-wait? sema) → boolean?
> sema : semaphore?

Like semaphore-wait, but semaphore-try-wait? never blocks execution. If sema’s internal counter is zero, semaphore-try-wait? returns #f immediately without decrementing the counter. If sema’s counter is positive, it is decremented and #t is returned.

> procedure (semaphore-wait/enable-break sema) → void?
> sema : semaphore?

Like semaphore-wait, but breaking is enabled (see Breaks) while waiting on sema. If breaking is disabled when semaphore-wait/enable-break is called, then either the semaphore’s counter is decremented or the exn:break exception is raised, but not both.

> procedure (semaphore-peek-evt sema) → semaphore-peek-evt?
> sema : semaphore?

Creates and returns a new synchronizable event (for use with sync, for example) that is ready for synchronization when sema is ready, but synchronizing the event does not decrement sema’s internal count. The synchronization result of a semaphore-peek event is the semaphore-peek event itself.

> procedure (semaphore-peek-evt? v) → boolean?
> v : any/c

Returns #t if v is a semaphore wrapper produced by semaphore-peek-evt, #f otherwise.

> > procedure
> > (call-with-semaphore |  | sema |  |  |  |
> > |  | proc |  |  |  |
> > | [ | try-fail-thunk] |  |  |  |
> > |  | arg ...) |  | → |  | any
> sema : semaphore?
> proc : procedure?
> try-fail-thunk : (or/c (-> any) #f) = #f
> arg : any/c

Waits on sema using semaphore-wait, calls proc with all args, and then posts to sema. A continuation barrier blocks full continuation jumps into or out of proc (see Prompts, Delimited Continuations, and Barriers), but escape jumps are allowed, and sema is posted on escape. If try-fail-thunk is provided and is not #f, then semaphore-try-wait? is called on sema instead of semaphore-wait, and try-fail-thunk is called if the wait fails.

> > procedure
> > (call-with-semaphore/enable-break |  | sema |  |  |  |
> > |  | proc |  |  |  |
> > | [ | try-fail-thunk] |  |  |  |
> > |  | arg ...) |  | → |  | any
> sema : semaphore?
> proc : procedure?
> try-fail-thunk : (or/c (-> any) #f) = #f
> arg : any/c

Like call-with-semaphore, except that semaphore-wait/enable-break is used with sema in non-try mode. When try-fail-thunk is provided and not #f, then breaks are enabled around the use of semaphore-try-wait? on sema.
top ← prev up next →