Struct ThreadManager

Source
pub struct ThreadManager { /* private fields */ }
Expand description

Simplified thread management for ThreadShare

ThreadManager is a standalone utility for managing threads with shared data, independent of the ThreadShare structures. It provides lightweight thread management with comprehensive tracking and error handling.

§Key Features

  • Simplified Thread Spawning: Spawn threads with descriptive names
  • Shared Data Management: Manage multiple types of shared data
  • Thread Tracking: Monitor active thread count and status
  • Automatic Thread Joining: Wait for all threads to complete
  • Type-Safe Operations: Compile-time guarantees for thread safety

§Example

use thread_share::{ThreadManager, share};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let manager = ThreadManager::new();
    let data = share!(vec![1, 2, 3]);

    // Spawn threads
    manager.spawn("sorter", data.clone(), |data| {
        data.update(|v| v.sort());
    })?;

    manager.spawn("validator", data.clone(), |data| {
        let v = data.get();
        for i in 1..v.len() {
            assert!(v[i-1] <= v[i]);
        }
    })?;

    // Wait for completion
    manager.join_all()?;
    Ok(())
}

§Thread Lifecycle

  1. Creation: ThreadManager::new() or ThreadManager::default()
  2. Spawning: manager.spawn(name, data, function) creates named threads
  3. Execution: Threads run with access to shared data
  4. Monitoring: Track active threads with active_threads()
  5. Completion: Wait for all threads with join_all()

§Performance

  • Thread Spawning: Minimal overhead over standard thread::spawn
  • Thread Tracking: Constant-time operations for thread management
  • Memory Usage: Small overhead for tracking structures
  • Scalability: Efficient for up to hundreds of threads

Implementations§

Source§

impl ThreadManager

Source

pub fn new() -> Self

Creates a new ThreadManager

This method creates a new ThreadManager instance with empty thread and shared data tracking.

§Returns

A new ThreadManager instance.

§Example
use thread_share::ThreadManager;

let manager = ThreadManager::new();
// let manager = ThreadManager::default(); // Alternative
Source

pub fn spawn<F, T>( &self, name: &str, shared_data: ThreadShare<T>, f: F, ) -> Result<(), String>
where F: FnOnce(ThreadShare<T>) + Send + 'static, T: Send + Sync + 'static,

Spawns a thread with access to shared data

This method creates a new thread with the given name and function. The thread receives a clone of the shared data and can safely modify it.

§Arguments
  • name - A descriptive name for the thread (useful for debugging)
  • shared_data - The ThreadShare<T> data to share with the thread
  • f - A function that receives ThreadShare<T> and performs the thread’s work
§Requirements

The function F must:

  • Implement FnOnce(ThreadShare<T>) - called once with shared data
  • Implement Send - safe to send across thread boundaries
  • Have 'static lifetime - no borrowed references

The type T must implement Send + Sync + 'static.

§Returns

Ok(()) on success, Err(String) if thread spawning fails.

§Example
use thread_share::{ThreadManager, share};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let manager = ThreadManager::new();
    let data = share!(0);

    // Spawn a worker thread
    manager.spawn("worker", data.clone(), |data| {
        for _ in 0..100 {
            data.update(|x| *x = *x + 1);
            std::thread::sleep(std::time::Duration::from_millis(10));
        }
    })?;

    // Spawn a monitor thread
    manager.spawn("monitor", data.clone(), |data| {
        for _ in 0..10 {
        std::thread::sleep(std::time::Duration::from_millis(100));
        println!("Current value: {}", data.get());
    }
    })?;
    Ok(())
}
Source

pub fn spawn_multiple<F, T>( &self, shared_data: ThreadShare<T>, thread_configs: Vec<(&str, F)>, ) -> Result<(), String>
where F: FnOnce(ThreadShare<T>) + Send + Clone + 'static, T: Send + Sync + 'static,

Spawns multiple threads with the same shared data

This method spawns multiple threads from a vector of configurations. Each configuration contains a thread name and a function.

§Arguments
  • shared_data - The ThreadShare<T> data to share with all threads
  • thread_configs - Vector of (name, function) tuples
§Requirements

The function F must implement Clone in addition to the standard requirements.

§Returns

Ok(()) on success, Err(String) if any thread spawning fails.

Source

pub fn join_all(&self) -> Result<(), String>

Waits for all threads to complete

This method blocks until all spawned threads have finished execution. It joins each thread and returns an error if any thread panics.

§Returns

Ok(()) when all threads complete successfully, Err(String) if any thread fails.

§Example
use thread_share::{ThreadManager, share};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let manager = ThreadManager::new();
    let data = share!(0);

    manager.spawn("worker", data.clone(), |data| {
        data.update(|x| *x = *x + 100);
    })?;

    // Wait for all threads to complete
    manager.join_all()?;

    // Now safe to access the final result
    assert_eq!(data.get(), 100);
    Ok(())
}
Source

pub fn active_threads(&self) -> usize

Gets the number of active threads

This method returns the current number of threads that are still running.

§Returns

The number of active threads.

§Example
use thread_share::{ThreadManager, share};
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let manager = ThreadManager::new();
    let data = share!(0);

    manager.spawn("worker", data.clone(), |data| {
        std::thread::sleep(Duration::from_millis(100));
    })?;

    println!("Active threads: {}", manager.active_threads()); // Prints: 1

    // Wait for completion
    manager.join_all()?;

    println!("Active threads: {}", manager.active_threads()); // Prints: 0
    Ok(())
}
Source

pub fn shared_data_count(&self) -> usize

Gets the number of shared data entries (for demonstration)

This method returns the number of shared data entries currently stored. It’s primarily used for demonstration and debugging purposes.

§Returns

The number of shared data entries.

§Example
use thread_share::ThreadManager;

let manager = ThreadManager::new();
println!("Shared data count: {}", manager.shared_data_count()); // Prints: 0
Source

pub fn is_complete(&self) -> bool

Checks if all threads have completed

This method returns true if there are no active threads, false otherwise.

§Returns

true if all threads have completed, false if any threads are still running.

§Example
use thread_share::{ThreadManager, share};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let manager = ThreadManager::new();
    let data = share!(0);

    manager.spawn("worker", data.clone(), |data| {
        data.update(|x| *x = *x + 1);
    })?;

    assert!(!manager.is_complete()); // Thread is still running

    manager.join_all()?;

    assert!(manager.is_complete()); // All threads completed
    Ok(())
}

Trait Implementations§

Source§

impl Default for ThreadManager

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.