目标:
- 多进程
- 多线程
- Rust的协程
多进程
use std::process::{Command, Stdio};fn main() {println!("call new exe in process:");// netstat -ntlp // 耗时很短,所以看不出效果// netstat -p // 耗时很长,如果可以异步输出,就好了let out = Command::new("netstat").arg("-ntlp").output().expect("echo failed!");println!("{}",String::from_utf8_lossy(out.stdout.as_slice()));println!("\r\nWait child run over...\r\n");// 必须piped 才能父子进程通信// spawn 切换到后台,只返回句柄let o1 = Command::new("netstat").arg("-p").stdout(Stdio::piped()).spawn().expect("o1 error");let out1 = o1.stdout.expect("stat error");let o2 = Command::new("grep").arg("tcp").stdin(Stdio::from(out1)).stdout(Stdio::piped()).spawn().expect("o2 error");let out2 = o2.wait_with_output().expect("wait error");println!("{}",String::from_utf8_lossy(out2.stdout.as_slice()));
}
多线程
use std::{thread, time::Duration};fn main() {println!("call function in thread:");thread::spawn(||{for i in 1..10 {let t = thread::current(); // // ThreadId(2), Noneprintln!("Thread Id:{:?} - {:?}, count: {}.", t.id(),t.name(),i);thread::sleep(1*Duration::from_secs(1));}});for i in 100..113 {let t = thread::current(); // ThreadId(1), Some("main")println!("main Id:{:?} - {:?}, count: {}.", t.id(),t.name(), i);thread::sleep(1*Duration::from_secs(1));}// name and waitlet th = thread::Builder::new().name("wait-th".to_string()).spawn(||{for i in 1..10 {let t = thread::current(); // ThreadId(3), Some("wait-th")println!("main2 Id:{:?} - {:?}, count: {}.", t.id(), t.name(), i);thread::sleep(1*Duration::from_secs(1));}}).unwrap();th.join().unwrap();// thread_local! 针对一个全局变量,多个线程共享初始值// 大部分场景下可以使用线程局部变量替代// 或者使用第三方thread-local库,支持线程结束后收集结果
}
协程
对于golang语言,使用的是有栈协程。使用栈和上下文切换来执行异步代码逻辑的机制。
Rust通过await, async, Future 支持无栈协程。内部生成了一个状态机以保证代码正确的流程。虽然使用起来没有golang的方便,但胜在效率很高。(早期有类似go的绿色线程GreenThread,现在已经抛弃)
但是,rust没有提供官方的运行时,需要社区驱动。比如futures, tokio, std-.
https://rust-lang.github.io/async-book
use std::{thread, time::Duration};
use async_std::task; // 依赖第三方运行时 async-stdasync fn hello() {for i in 1..10{println!("[hello] id: {:?} - {:?}, {}.", thread::current().id(), task::current().id(), i);task::sleep(Duration::from_secs(1)).await;}
}async fn world(){for i in 1..15{println!("[world] id: {:?} - {:?}, {}.", thread::current().id(), task::current().id(),i);task::sleep(Duration::from_secs(1)).await;}
}fn main() {let _f1 = task::spawn(hello());task::block_on(world());
}
协程的并发需要依赖第三方库,目前支持1:N, N:M 模型,可以在一个线程池里完成N:M模型的并发。