Scheme 48 Manual | Contents | In Chapter: Threads
Previous: Mutual exclusion | Next: Mutual exclusion

Mutual exclusion

Scheme 48 also has more traditional mutual-exclusion synchronization abstractions, specifically mutex locks and placeholders. Note that typically synchronization via optimistic concurrency is usually preferable: Mutual exclusion often puts the running program into an inconsistent state for the time of the inclusion, which has adverse effects on modularity and interruptibility.

Locks

The locks structure contains bindings that implement standard mutex locks:

Make-lock creates a lock in the "released" state. Lock? is the predicate for locks.

Obtain-lock atomically checks if lock is in the "released" state. If it is, the lock is put into the "obtained" state, and obtain-lock returns immediately. If the lock is in the "obtained" state, the current thread is suspended and registered with the lock. Maybe-obtain-lock, like obtain-lock, checks the state of lock: if it is "released," the lock is put into the "obtained" state, if it is "obtained," maybe-obtain-lock returns immediately. Maybe-obtain-lock returns #t if it was able to obtain the lock, and #f otherwise.

Release-lock does nothing if lock is in the "released" state. If it is in the "obtained" state, release-lock causes one of the threads suspended on an obtain-lock lock operation to continue execution. If that thread is the last thread registered with the lock, the lock is transferred to the "released" state. In any case, release-lock returns immediately.

Placeholders

The placeholders structure contains bindings for placeholders--thread-safe, write-once variables, akin to ID-90 I-structures or CML I-variables.

The typical scenario for placeholders is that, say, a thread A computes a value needed by another thread B at some unspecified time. Both threads share access to a placeholder; when A has computed the value, it places it into the placeholder. When B needs the value, it extracts it from placeholder, blocking if necessary.

Make-placeholder creates an empty placeholder. (The optional id argument is only for debugging purposes; the discloser for placeholders prints it out if present.) Placeholder? is the predicate for placeholders.

Placeholder-set! places a value into a placeholder. Doing this more than once signals an error. Placeholder-value extracts the value from the placeholder and returns it. If the placeholder is empty, it blocks the current thread until it becomes full.

Previous: Mutual exclusion | Next: Mutual exclusion