Import std.concurrent.locks
std.concurrent.locks
Semaphores, barriers, wait groups, Once, and read-write locks, for any thread.
The locks any thread can use at once, over the runtime's: a Semaphore of permits, a Barrier
that threads meet at, a WaitGroup that waits for work under way, a Once that runs its work one
time, and an RwLock<T>, whose value many threads read at once, or one writes alone. Each is a
Shared Class, so a Const or a parameter shares one with the work that Spawn and Thread.Start
run. What waits blocks its thread and runs nothing else meanwhile, as a Channel's Send and
Receive do, so work that waits on the pool holds its worker: work that waits for other work
belongs on a Thread, or the pool can be left with no worker for what it waits for. A
Semaphore's Acquire and a WaitGroup's Wait can take a Cancellation, which stops the wait.
std/concurrent/locks.fb
Types
Semaphore
class
Public Shared Class Semaphore
Permits that threads take and give back: Acquire takes one, waiting while there's none, and Release gives them back, so no more threads than there are permits go on at once.
Examples
Const permits = Semaphore(2)
Expect(permits.TryAcquire() && permits.TryAcquire())
Expect(!permits.TryAcquire())
permits.Release()
Expect(permits.Available == 1)std/concurrent/locks.fb, line 58
-
A Semaphore with
countpermits. Panics when that's negative. -
Takes a permit, waiting while there's none.
-
Takes a permit, waiting while there's none, unless the cancellation is cancelled first, or is already, which throws a CancelledError and takes none.
-
Takes a permit unless there's none, and tells whether it did.
-
Gives back
countpermits, which needn't be ones Acquire took, waking as many threads waiting for one. Panics whencountisn't 1 or more, or when it would take the permits past what an Int holds. -
How many permits there are now, which other threads may change at any time.
Barrier
class
Public Shared Class Barrier
Where a number of threads meet, round after round: each one's Wait returns once they've all come, which starts the next round.
Examples
Global lasts = Atomic<Int>(0)
Const meet = Barrier(2)
Function Arrive()
If meet.Wait() Then lasts.Add(1)
End Function
Local other = Spawn(Arrive)
Arrive()
other.Wait()
// One of the two is the round's last.
Expect(lasts.Load() == 1)std/concurrent/locks.fb, line 124
-
A Barrier that
countthreads meet at each round. Panics unless that's 1 or more. -
Waits until the round's last thread comes, and then they all go on. Gives True to that last one, and False to the others, so one of them can do what's done once a round.
-
How many threads meet at it each round.
WaitGroup
class
Public Shared Class WaitGroup
A count of the work under way, which Wait waits to see at 0: Add counts work before it starts, and Done says that some is done.
Examples
Global finished = Atomic<Int>(0)
Const work = WaitGroup()
Function Step()
finished.Add(1)
work.Done()
End Function
work.Add(3)
For i = 1 To 3
Spawn(Step)
End For
work.Wait()
Expect(finished.Load() == 3)std/concurrent/locks.fb, line 172
-
A WaitGroup counting 0.
-
Adds
count, which can be negative, to the work it counts, and wakes the threads waiting once that's 0. Panics when it would take that below 0, or past what an Int holds. -
Takes 1 from the count. Panics when it's 0, since Done would be once more than Add counted.
-
Waits until the count is 0, which it may be already.
-
Waits until the count is 0 unless the cancellation is cancelled first, or is already, which throws a CancelledError.
-
The count now, which other threads may change at any time.
Once
class
Public Shared Class Once
Work that runs one time: the first Do runs it, and every other, at once or after, on any thread, returns once it has run.
Examples
Global runs = Atomic<Int>(0)
Const setup = Once()
Function CountRun()
runs.Add(1)
End Function
Parallel For i = 0 Until 8
setup.Do(CountRun)
End For
Expect(runs.Load() == 1 && setup.IsDone)std/concurrent/locks.fb, line 241
-
A new Once, whose work hasn't run.
-
Runs
work, unless a Do has, waiting while another thread's Do runs it. Panics in a Do that theworkitself calls, which would wait for itself forever. -
Whether the work has run.
RwLock
class
Public Shared Class RwLock<T: Sendable>
A value that many threads can read at once, or one can write while no other reads it. A Read gives what its Function makes of the value, and a Write gives the value what its Function makes of it, which no Read sees half done. A writer that waits goes before the readers that come after it, so it isn't kept waiting forever.
Examples
Const total = RwLock<Int>(0)
total.Write(Function(n: Int) => n + 5)
Expect(total.Read(Function(n: Int) => n * 2) == 10)
Expect(total.Value == 5)std/concurrent/locks.fb, line 286
-
A new RwLock that holds
value. -
What
readergives for the value, which no thread writes meanwhile, though others may read it. Panics when this thread reads or writes it already, in a reader or a writer, which a writer waiting between could keep waiting forever. -
Gives the value what
writergives for it, while no other thread reads or writes it. The old value goes once the Write holds no lock, so a Destroy that its going runs can use the RwLock. Panics when this thread reads or writes it already, which would wait for itself forever. -
A copy of the value, as a Read gives it, or a new value, as a Write gives it.
Report an issue with this page or with FutureBlitz on GitHub.