thread

作者: allenhaozi | 来源:发表于2020-04-09 15:57 被阅读0次

使用 spawn 创建新线程

use std::thread;
use std::time::Duration;
fn main() {
    thread::spawn(|| {
           for i in 1..10 {
                   println!("hi number {} from the spawned thread!", i);           
                   thread::sleep(Duration::from_millis(1));
           } 
    });
   for i in 1..5 {
       println!("hi number {} from the main thread!", i); 
       thread::sleep(Duration::from_millis(1));
    } 
}

使用 join 等待所有线程结束

use std::thread;
use std::time::Duration;
fn main() {
    let handle = thread::spawn(|| {
           for i in 1..10 {
                   println!("hi number {} from the spawned thread!", i); 
                  thread::sleep(Duration::from_millis(1));
           } 
     });
     for i in 1..5 {
            println!("hi number {} from the main thread!", i); 
            thread::sleep(Duration::from_millis(1));
      }
     // 这两个线程仍然会交替执行,
     // 不过主线程会由于 handle.join() 调用会等待直到新建线程执行完毕
     // 
     handle.join().unwrap(); }

将handle.join()提前

use std::thread;
use std::time::Duration;
fn main() {
        let handle = thread::spawn(|| {
               for i in 1..10 {
                     println!("hi number {} from the spawned thread!", i); 
                     thread::sleep(Duration::from_millis(1));
                } 
         });
         // 主线程会等待直到新建线程执行完毕之后才开始执行 for 循环
         // 所以输出将不会交替出现,
         handle.join().unwrap();
         for i in 1..5 {
               println!("hi number {} from the main thread!", i); 
               thread::sleep(Duration::from_millis(1));
         }
 }

线程与 move 闭包

move 闭包,其经常与 thread::spawn 一起使用允许我们在一个线程中使用另一个线程的数据。

通过在闭包之前增加 move 关键字,强制闭包获取其使用的值的所有权

use std::thread;
fn main() {
    let v = vec![1, 2, 3];
    let handle = thread::spawn(move || {
        println!("Here's a vector: {:?}", v);
});
handle.join().unwrap(); }

闭包引用后,我们尝试drop v

use std::thread;
fn main() {
    let v = vec![1, 2, 3];
    let handle = thread::spawn(|| {
        println!("Here's a vector: {:?}", v);
});
// 使用 move 关键字强制闭包获取其使用的值的所有权
// 保证主线程不会再使用 v 
// 那么当在主线程中使用 v 时就会违反所有权规则
drop(v); // oh no!
handle.join().unwrap(); }

使用消息传递在线程间传送数据

Rust 中一个实现消息传递并发的主要工具是 通道(channel)

use std::thread;
use std::sync::mpsc;
fn main() {
    // 发送端和接收端
    // multi producer single comsumer
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
           let val = String::from("hi"); 
           // send 方法返回一个Result<T, E> 类型,
           // 所以如果接收端已经被丢弃了,将没有发送值的目标,
           // 所以发送操作会返回错误
           // 在这个例子中,出错的时候调用 unwrap 产生 panic
           tx.send(val).unwrap();

           // 方法会阻塞主线程执行直到从通道中接收一个值
           // recv 和 try_recv 不会堵塞 
           let received = rx.recv().unwrap();
           println!("Got: {}", received);
    }); 
}

发送多个值

use std::thread;
use std::sync::mpsc;
use std::time::Duration;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        let vals = vec![
            String::from("hi"),
            String::from("from"),
            String::from("the"),
            String::from("thread"),
];
for val in vals {
tx.send(val).unwrap(); thread::sleep(Duration::from_secs(1));
} });
    for received in rx {
        println!("Got: {}", received);
} }

通过clone创建多个生产者

# use std::thread;
# use std::sync::mpsc;
# use std::time::Duration; #
# fn main() {
// --snip--
let (tx, rx) = mpsc::channel();
let tx1 = mpsc::Sender::clone(&tx);
thread::spawn(move || {
    let vals = vec![
        String::from("hi"),
        String::from("from"),
        String::from("the"),
        String::from("thread"),
];
for val in vals {
tx1.send(val).unwrap(); thread::sleep(Duration::from_secs(1));
} });
thread::spawn(move || {
    let vals = vec![
        String::from("more"),
        String::from("messages"),
        String::from("for"),
        String::from("you"),
];
for val in vals {
tx.send(val).unwrap(); thread::sleep(Duration::from_secs(1));
} });
for received in rx {
    println!("Got: {}", received);
}
// --snip--
#}

相关文章

网友评论

      本文标题:thread

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