Untitled

 avatar
unknown
plain_text
2 years ago
1.9 kB
3
Indexable
use std::sync::{Arc, Condvar, Mutex};
use std::sync::mpsc::{Sender, Receiver, channel};


struct CyclicBarrier{
    num_threads: usize,
    senders: Vec<Sender<()>>,
    receivers: Vec<Receiver<()>>
}

struct ThreadBarrier {
    senders: Vec<Sender<()>>,
    receiver: Receiver<()>
}

impl CyclicBarrier{
    fn new(n: usize) -> Self{
        let mut  senders = Vec::new();
        let mut receivers = Vec::new();
        for i in 0..n {
            let (sender, receiver) = channel();
            senders.push(sender);
            receivers.push(receiver);
        }
        return CyclicBarrier{
            num_threads: n,
            senders,
            receivers
        }
    }

    fn strvec(&mut self) -> Vec<ThreadBarrier> {
        let n = self.num_threads;
        let mut res = Vec::new();
        for i in 0..n{
            res.push(ThreadBarrier{
                senders: self.senders.clone(),
                receiver: self.receivers.remove(0)
            })
        }
        return res;
    }
}

impl ThreadBarrier{
    fn wait(&self, num: usize){
        for i in 0..self.senders.len(){
            if i != num {
                self.senders[i].send(());
            }
        }
        for i in 0..self.senders.len()-1{
            self.receiver.recv();
        }
    }
}

fn main() {
    //let abarrier = Arc::new(CyclicBarrier::new(3));
    let abarrier = CyclicBarrier::new(3);
    let cbarriers = abarrier.strvec();
    let mut vt = Vec::new();
    for (i, item) in cbarriers.iter().enumerate() {
        //let cbarrier = abarrier.clone();
        vt.push(std::thread::spawn(move || {
            for j in 0..10 {
                item.wait(i);
                println!("after barrier {} {}", i, j);
            }
        }));
    }
    for t in vt {
        t.join().unwrap();
    }
}