30.并发.rs

/*
安全高效的处理并发是 Rust 诞生的目的之一,主要解决的是服务器高负载承受能力。
并发(concurrent)的概念是只程序不同的部分独立执行,这与并行(parallel)的概念容易混淆,并行强调的是"同时执行"。
Rust 中通过 std::thread::spawn 函数创建新线程.
*/use std::sync::mpsc;
use std::thread;
use std::time::Duration;fn spawn_function() {for i in 0..5 {println!("spawned thread print {}", i);thread::sleep(Duration::from_millis(1));}
}fn test_1() {//std::thread::spawn 函数的参数是一个无参函数thread::spawn(spawn_function); //随着主线程的结束,spawn 线程也随之结束了,并没有完成所有打印。for i in 0..3 {println!("main thread print {}", i);thread::sleep(Duration::from_millis(1));}
}/*
可以使用闭包(closures)来传递函数作为参数
闭包是可以保存进变量或作为参数传递给其他函数的匿名函数。闭包相当于 C++ 中的 Lambda 表达式,格式如下:|参数1, 参数2, ...| -> 返回值类型 {// 函数体
}
*/
fn test_2() {thread::spawn(|| {for i in 0..5 {println!("spawned thread print {}", i);thread::sleep(Duration::from_millis(1));}});for i in 0..3 {println!("main thread print {}", i);thread::sleep(Duration::from_millis(1));}
}//闭包练习使用
fn test_3() {let inc = |num: i32| -> i32 { num + 1 };println!("inc(5) = {}", inc(5));//闭包可以省略类型声明使用 Rust 自动类型判断机制:let inc = |num| num + 1;println!("inc(5) = {}", inc(5));
}//join 方法.
fn test_4() {let handle = thread::spawn(|| {for i in 0..5 {println!("spawned thread print {}", i);thread::sleep(Duration::from_millis(1));}});for i in 0..3 {println!("main thread print {}", i);thread::sleep(Duration::from_millis(1));}//join 方法可以使子线程运行结束后再停止运行程序。handle.join().unwrap();
}//move 强制所有权迁移
fn test_5() {let s = "hello".to_string();// 在子线程中尝试使用当前函数的资源,这一定是错误的!因为所有权机制禁止这种危险情况的产生,它将破坏所有权机制销毁资源的一定性。// let handle = thread::spawn(|| {//      println!("{}", s);// });// 我们可以使用闭包的 move 关键字来处理:let handle = thread::spawn(move || {//s.push_str("122222");println!("{}", s);});//转移之后外面仍然可以用,s是String就不可用了//println!("{}", s);handle.join().unwrap();
}//Rust 中一个实现消息传递并发的主要工具是通道(channel),通道有两部分组成,发送者(transmitter)和接收者(receiver)。
//std::sync::mpsc 包含了消息传递的方法:
fn test_6() {let (tx, rx) = mpsc::channel();let handle = thread::spawn(move || {thread::sleep(Duration::from_millis(1000));let hello = String::from("hello");let world = String::from("world");tx.send(hello).unwrap();tx.send(world).unwrap();});//handle.join().unwrap();//这个就收是阻塞式调用,直到有数据才会解锁//let received = rx.recv();//println!("only recv, no unwrap");let received = rx.recv().unwrap();println!("Got: {}", received);//如果发送是多次发送,那么接受也必须是多次接收let received = rx.recv().unwrap();println!("Got: {}", received);//如果对面没有内容了,还进行接收那就返回空let received = rx.recv();match received {Ok(str) => println!("Got: {}", str),Err(e) => println!("got nothing")}//println!("Got: {}", received);
}/*
https://rustcc.gitbooks.io/rustprimer/content/rcarc/mutex.html
Mutex 意为互斥对象,用来保护共享数据。Mutex 有下面几个特征:
Mutex 会等待获取锁令牌(token),在等待过程中,会阻塞线程。直到锁令牌得到。同时只有一个线程的 Mutex 对象获取到锁;
Mutex 通过 .lock() 或 .try_lock() 来尝试得到锁令牌,被保护的对象,必须通过这两个方法返回的 RAII 守卫来调用,不能直接操作;
当 RAII 守卫作用域结束后,锁会自动解开;
在多线程中,Mutex 一般和 Arc 配合使用。*/
use std::{sync::RwLock, thread};
use std::{sync::{mpsc::channel, Arc, Mutex},time::Duration,
};
const N: usize = 20;fn test_7() {println!("-----------------------test7-----------------------");let mutex = Arc::new(Mutex::new(0));for _ in 0..3 {let mutex2 = mutex.clone();thread::spawn(move || loop {let mut data = mutex2.lock().unwrap();*data += 1;if *data > N {break;}let tid = thread::current().id();println!("{:?}--{}", tid, data);});}thread::sleep(Duration::from_secs(1));
}fn test_8() {println!("-----------------------test8-----------------------");let mutex = Arc::new(Mutex::new(0));let (tx, rx) = channel();for _ in 0..3 {let (mutex2, tx) = (mutex.clone(), tx.clone());thread::spawn(move || loop {let mut data = mutex2.lock().unwrap();*data += 1;let tid = thread::current().id();tx.send((tid, *data)).unwrap();if *data >= N {break;}});}for _ in 0..N {let (tid, data) = rx.recv().unwrap();println!("{:?}--{}", tid, data);}
}//RwLock 读写锁
//同时允许多个读,最多只能有一个写;读和写不能同时存在;
fn test_9() {println!("-----------------------test9-----------------------");let lock = RwLock::new(5);// many reader locks can be held at once{let r1 = lock.read().unwrap();let r2 = lock.read().unwrap();assert_eq!(*r1, 5);assert_eq!(*r2, 5);}// only one write lock may be held, however{let mut w = lock.write().unwrap();*w += 1;assert_eq!(*w, 6);}
}fn main() {test_1();test_2();test_3();test_4();test_5();test_6();test_7();test_8();test_9();
}

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部