mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-26 00:00:16 +02:00
docs: add countdown latch example to Semaphore
## Motivation Some users have requested that `tokio::sync` add a countdown latch synchronization primitive. This can be implemented using the existing `Semaphore` API, so rather than adding a countdown latch type, we should add documentation examples showing how the `Semaphore` can be used as a countdown latch. ## Solution This branch adds an example to the `tokio::sync::Semaphore` docs demonstrating its usage as a countdown latch. This example was extracted from https://github.com/tokio-rs/tokio/issues/6087#issuecomment-1771452743. Closes #6087
This commit is contained in:
@@ -322,7 +322,7 @@ use std::sync::Arc;
|
||||
/// # #[tokio::main(flavor = "current_thread", start_paused = true)]
|
||||
/// async fn main() {
|
||||
/// let capacity = 5;
|
||||
/// let update_interval = Duration::from_secs_f32(1.0 / capacity as f32);
|
||||
/// let update_interval = Duration::from_secs_f32(1.0 / capacity as f32);
|
||||
/// let bucket = TokenBucket::new(update_interval, capacity);
|
||||
///
|
||||
/// for _ in 0..5 {
|
||||
@@ -333,6 +333,76 @@ use std::sync::Arc;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ## Countdown latch
|
||||
///
|
||||
/// A `Semaphore` may be used to implement a countdown latch, a synchronization
|
||||
/// primitive where one task waits until a set number of other tasks to have
|
||||
/// completed before continuing.
|
||||
///
|
||||
/// The task awaiting the countdown should call [`Semaphore::acquire_many`] to
|
||||
/// acquire the a number of permits equal to the number of tasks which hold the
|
||||
/// latch open. The tasks whose completion is awaited by the latch should call
|
||||
/// [`Semaphore::add_permit`] with a single permit to increment the countdown
|
||||
/// latch as they complete. For example:
|
||||
///
|
||||
/// ```rust
|
||||
/// use tokio::sync::Semaphore;
|
||||
/// use std::{future::Future, sync::Arc};
|
||||
///
|
||||
/// /// A token that holds a countdown latch open until it is dropped.
|
||||
/// #[derive(Clone)]
|
||||
/// pub struct Countdown(Arc<Semaphore>);
|
||||
///
|
||||
/// impl Drop for Countdown {
|
||||
/// fn drop(&mut self) {
|
||||
/// self.0.add_permits(1);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl Countdown {
|
||||
/// /// Returns a new countdown latch which completes when `n` tasks
|
||||
/// /// have exited.
|
||||
/// ///
|
||||
/// /// This method returns a tuple of a `Countdown` token which
|
||||
/// /// holds the latch open and incrememts the count of completed
|
||||
/// /// tasks when it is dropped, and a `Future` which completes when
|
||||
/// /// `n` clones of the `Countdown` token have been dropped.
|
||||
/// pub fn latch(n: u32) -> (Self, impl Future + Send) {
|
||||
/// let sem = Arc::new(Semaphore::new(0));
|
||||
/// let latch = Self(sem.clone());
|
||||
///
|
||||
/// let wait = async move {
|
||||
/// let _ = sem.acquire_many(n).await;
|
||||
/// };
|
||||
///
|
||||
/// (latch, wait)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// #[tokio::main]
|
||||
/// async fn main() {
|
||||
/// let (latch, wait) = Countdown::new(5);
|
||||
/// for i in 1..=5 {
|
||||
/// let latch = latch.clone();
|
||||
/// tokio::spawn(async move {
|
||||
/// // move the latch into the task.
|
||||
/// let _latch = latch;
|
||||
///
|
||||
/// // do stuff...
|
||||
/// println!("countdown task {i} running...");
|
||||
/// tokio::task::yield_now().await;
|
||||
///
|
||||
/// // when the task completes, the latch is dropped.
|
||||
/// println!("countdown task {i} done!");
|
||||
/// });
|
||||
/// }
|
||||
///
|
||||
/// println!("waiting for tasks to complete...");
|
||||
/// wait.await;
|
||||
/// println!("tasks completed!");
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`PollSemaphore`]: https://docs.rs/tokio-util/latest/tokio_util/sync/struct.PollSemaphore.html
|
||||
/// [`Semaphore::acquire_owned`]: crate::sync::Semaphore::acquire_owned
|
||||
#[derive(Debug)]
|
||||
|
||||
Reference in New Issue
Block a user