美文网首页Rust 学习笔记
rust - 多线程学习笔记

rust - 多线程学习笔记

作者: 国服最坑开发 | 来源:发表于2020-02-22 15:07 被阅读0次

    0x01 最一般的用法

    use std::str;
    use std::thread;
    
    fn main() {
        let mut v = vec![];
        for id in 0..5{
            let child = thread::spawn(move || {
                println!("in child: {}", id);
            });
            v.push(child);
        }
    
        println!("in main : join before");
    
        for child in v {
            child.join();
        }
    
        println!("in main : join after");
    }
    

    结果:

    in child: 0
    in child: 1
    in child: 2
    in main : join before
    in child: 3
    in child: 4
    in main : join after
    

    0x02 定制线程参数

    use std::str;
    use std::thread;
    use std::panic;
    use std::thread::{Builder, current};
    
    fn main() {
        let mut v = vec![];
        for id in 0..5 {
            let thread_name = format!("child-{}", id);
            let size:usize = 3*1024;
            let builder = Builder::new().name(thread_name).stack_size(size);
            let child = builder.spawn(move ||{
                println!("in child : {}", id);
                if id == 3 {
                    // panic::catch_unwind(||{
                    //     panic!("oh no!");
                    // });
                    println!("in {} do sm", current().name().unwrap());
                }
            }).unwrap();
            v.push(child);
        }
    
        for child in v{
            child.join().unwrap();
        }
    }
    

    结果

    in child : 1
    in child : 0
    in child : 3
    in child-3 do sm
    in child : 4
    in child : 2
    

    0x03 ThreadLocal 线程安全变量

    use std::str;
    use std::thread;
    use std::panic;
    use std::thread::{Builder, current};
    
    
    use std::cell::RefCell;
    
    fn main() {
        // create a thread local static var
        thread_local!(static FOO:RefCell<u32> = RefCell::new(1));
        FOO.with(|f|{
            // in main thread : check if 1, and assign to 2
            assert_eq!(*f.borrow(), 1);
            *f.borrow_mut() = 2;
        });
    
        let m = thread::spawn(||{
            FOO.with(|f| {
                // in sub thread: check 1, and assign to 3
                assert_eq!(*f.borrow(),1);
                *f.borrow_mut() = 3;
            });
        });
    
        m.join();
    
        FOO.with(|f|{
            // in main thread: check 2
            assert_eq!(*f.borrow(), 2);
        });
    }
    

    结论就是, 没啥输出. 主线程里更新成2后, 子线程的修改, 不影响主线程的内容.

    0x04 线程阻塞&打开

    park(): 阻塞线程, unpack(): 手动激活线程
    thread::sleep 当前线程睡一段时间后, 自动后续执行

    use std::str;
    use std::thread;
    use std::panic;
    use std::thread::{Builder, current};
    use std::time::Duration;
    
    fn main() {
        let parked_thread = thread::Builder::new().spawn(|| {
            println!("Parking thread");
            thread::park();
            println!("Thread unparked");
        }).unwrap();
    
        thread::sleep(Duration::from_millis(1000));
        println!("Unpack the thread" );
       
        parked_thread.thread().unpark();
        parked_thread.join().unwrap();
    
        println!("Done!");
    }
    

    结果

    Parking thread
    Unpack the thread
    Thread unparked
    Done!
    

    0x05 线程锁 Mutex

    跨线程更新数据 , 需要对线程进行上锁. Mutex::lock()

    use std::str;
    use std::thread;
    use std::panic;
    use std::thread::{Builder, current};
    use std::time::Duration;
    
    use std::sync::{Arc, Mutex};
    
    fn main() {
        let mut s = Arc::new(Mutex::new("Hello".to_string()));
        let mut v = vec![];
    
        for _ in 0..3 {
            let mut s_clone = s.clone();
            let child = thread::spawn(move || {
                let mut s_clone = s_clone.lock().unwrap();
                s_clone.push_str(" Rust!");
            });
            v.push(child);
        }
    
        for c in v {
            c.join();
        }
    
        println!("{:?}", s);
    }
    
    

    输出

    Mutex { data: "Hello Rust! Rust! Rust!" }
    

    0x06 Barrier, 线程等待

    use std::str;
    use std::thread;
    use std::panic;
    use std::thread::{Builder, current};
    use std::time::Duration;
    
    use std::sync::{Arc, Mutex, Barrier};
    
    fn main() {
        let mut handles = Vec::with_capacity(5);
        let barrier = Arc::new(Barrier::new(5));
    
        for _ in 0..5 {
            let c = barrier.clone();
            handles.push(thread::spawn(move || {
                println!("before wait");
                c.wait();
                println!("after wait");
            }))
        }
        
        for handle in handles {
            handle.join().unwrap();
        }
    }
    

    结果

    before wait
    before wait
    before wait
    before wait
    before wait
    after wait
    after wait
    after wait
    after wait
    after wait
    

    0x07 Channel 通信

    chanel . recv 会阻塞当前线程

    use std::str;
    use std::thread;
    use std::panic;
    use std::thread::{Builder, current};
    use std::time::Duration;
    
    use std::sync::{Arc, Mutex, Barrier};
    
    use std::sync::mpsc::channel;
    
    fn main() {
        let (tx, rx) = channel();
        thread::spawn(move || {
            thread::sleep(Duration::from_millis(1000));
            tx.send(10).unwrap();
        });
    
        let r = rx.recv().unwrap();
        assert_eq!(r, 10);
        println!("{}", r);
    }
    
    

    结果 : 10

    相关文章

      网友评论

        本文标题:rust - 多线程学习笔记

        本文链接:https://www.haomeiwen.com/subject/enjlqhtx.html