pub fn initialize<T:Send+'static, F: Fn(Generic)->T+Send+Sync+'static>(
    config: Config,
    func: F,
) -> Result<WorkerGuards<T>,String> {
    let (allocators, others) = config.try_build()?;
    initialize_from(allocators, others, func)
}
/// Initializes communication and executes a distributed computation.
///
/// This method allocates an `allocator::Generic` for each thread, spawns local worker threads,
/// and invokes the supplied function with the allocator.
/// The method returns a `WorkerGuards<T>` which can be `join`ed to retrieve the return values
/// (or errors) of the workers.
///
///
/// # Examples
/// ```
/// use timely_communication::Allocate;
///
/// // configure for two threads, just one process.
/// let config = timely_communication::Config::Process(2);
///
/// // initializes communication, spawns workers
/// let guards = timely_communication::initialize(config, |mut allocator| {
///     println!("worker {} started", allocator.index());
///
///     // allocates a pair of senders list and one receiver.
///     let (mut senders, mut receiver) = allocator.allocate(0);
///
///     // send typed data along each channel
///     use timely_communication::Message;
///     senders[0].send(Message::from_typed(format!("hello, {}", 0)));
///     senders[1].send(Message::from_typed(format!("hello, {}", 1)));
///
///     // no support for termination notification,
///     // we have to count down ourselves.
///     let mut expecting = 2;
///     while expecting > 0 {
///         allocator.receive();
///         if let Some(message) = receiver.recv() {
///             use std::ops::Deref;
///             println!("worker {}: received: <{}>", allocator.index(), message.deref());
///             expecting -= 1;
///         }
///         allocator.release();
///     }
///
///     // optionally, return something
///     allocator.index()
/// });
///
/// // computation runs until guards are joined or dropped.
/// if let Ok(guards) = guards {
///     for guard in guards.join() {
///         println!("result: {:?}", guard);
///     }
/// }
/// else { println!("error in computation"); }
/// ```
///
/// The should produce output like:
///
/// ```ignore
/// worker 0 started
/// worker 1 started
/// worker 0: received: <hello, 0>
/// worker 1: received: <hello, 1>
/// worker 0: received: <hello, 0>
/// worker 1: received: <hello, 1>
/// result: Ok(0)
/// result: Ok(1)
/// ```
Initializes communication and executes a distributed computation.
This method allocates an `allocator::Generic` for each thread, spawns local worker threads,
and invokes the supplied function with the allocator.
The method returns a `WorkerGuards` which can be `join`ed to retrieve the return values
(or errors) of the workers.
Initializes communication and executes a distributed computation . This method allocates an ` allocator :: Generic ` for each thread spawns local worker threads and invokes the supplied function with the allocator . The method returns a ` WorkerGuards ` which can be ` join ` ed to retrieve the return values ( or errors ) of the workers .
pub fn initialize<T:Send+'static, F: Fn(Generic)->T+Send+Sync+'static>(
    config: Config,
    func: F,
) -> Result<WorkerGuards<T>,String> {
    let (allocators, others) = config.try_build()?;
    initialize_from(allocators, others, func)
}
pub fn initialize < T : Send + ' static , F : Fn ( Generic ) -> T + Send + Sync + ' static > ( config : Config , func : F , ) -> Result < WorkerGuards < T > , String > { let ( allocators , others ) = config . try_build ( ) ? ; initialize_from ( allocators , others , func ) }
Initializes communication and executes a distributed computation.
Initializes communication and executes a distributed computation .
config
Config
func
F
examples
```
use timely_communication::Allocate.

configure for two threads, just one process.
let config = timely_communication::Config::Process(2).

initializes communication, spawns workers
let guards = timely_communication::initialize(config, |mut allocator| {
println!("worker {} started", allocator.index()).

allocates a pair of senders list and one receiver.
let (mut senders, mut receiver) = allocator.allocate(0).

send typed data along each channel
use timely_communication::Message;
senders[0].send(Message::from_typed(format!("hello, {}", 0)));
senders[1].send(Message::from_typed(format!("hello, {}", 1))).

no support for termination notification,
we have to count down ourselves.
let mut expecting = 2;
while expecting > 0 {
allocator.receive();
if let Some(message) = receiver.recv() {
use std::ops::Deref;
println!("worker {}: received: <{}>", allocator.index(), message.deref());
expecting -= 1;
}
allocator.release();
}

optionally, return something
allocator.index()
}).

computation runs until guards are joined or dropped.
if let Ok(guards) = guards {
for guard in guards.join() {
println!("result: {:?}", guard);
}
}
else { println!("error in computation"); }
```

The should produce output like.

```ignore
worker 0 started
worker 1 started
worker 0: received: 
worker 1: received: 
worker 0: received: 
worker 1: received: 
result: Ok(0)
result: Ok(1)
```
` ` ` use timely_communication :: Allocate . configure for two threads just one process . let config = timely_communication :: Config :: Process ( 2 ) . initializes communication spawns workers let guards = timely_communication :: initialize ( config |mut allocator| { println! ( " worker {} started " allocator . index () ) . allocates a pair of senders list and one receiver . let ( mut senders mut receiver ) = allocator . allocate ( 0 ) . send typed data along each channel use timely_communication :: Message ; senders [ 0 ] . send ( Message :: from_typed ( format! ( " hello {} " 0 ))) ; senders [ 1 ] . send ( Message :: from_typed ( format! ( " hello {} " 1 ))) . no support for termination notification we have to count down ourselves . let mut expecting = 2 ; while expecting > 0 { allocator . receive () ; if let Some ( message ) = receiver . recv () { use std :: ops :: Deref ; println! ( " worker {} : received : < {} > " allocator . index () message . deref () ) ; expecting - = 1 ; } allocator . release () ; } optionally return something allocator . index () } ) . computation runs until guards are joined or dropped . if let Ok ( guards ) = guards { for guard in guards . join () { println! ( " result : { : ? } " guard ) ; } } else { println! ( " error in computation " ) ; } ` ` ` The should produce output like . ` ` ` ignore worker 0 started worker 1 started worker 0 : received : worker 1 : received : worker 0 : received : worker 1 : received : result : Ok ( 0 ) result : Ok ( 1 ) ` ` `