tokio
tokio构建可靠的网络应用程序,同时不牺牲速度。
tokio是Rust编程语言的异步运行时。它提供了编写网络应用程序所需的构建块。它提供了针对各种系统的灵活性,从拥有数十个内核的大型服务器到小型嵌入式设备。
异步运行时
编程方式定义运行时
[dependencies]
tokio = {version = "^1", features = ["rt", "time"]}use std::time;
fn main() {
let duration = time::Duration::from_secs(1);
tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.unwrap()
.block_on(async {
tokio::time::sleep(duration).await;
println!("hello");
})
}tokio::runtime::Builder::new_current_thread(): 创建了一个新的Tokio运行时构建器。new_current_thread()表示创建一个单线程的运行时。对于简单的例子或者只需要在一个线程中运行异步代码的情况,单线程运行时就足够了。.enable_time(): 这一步启用了Tokio运行时的定时器功能。如果没有启用定时器,tokio::time::sleep()将无法工作。.build(): 这根据构建器的配置创建一个Tokio运行时。.unwrap(): 由于build()方法返回一个Result,这里使用unwrap()来处理可能出现的错误。在实际生产代码中,应该使用更健壮的错误处理方式,例如match或?操作符。.block_on(async { ... }): 这是Tokio运行时提供的用于运行异步代码块的方法。block_on会阻塞当前线程,直到提供的async块执行完成。async { ... }: 这是一个异步代码块。在这个块中,我们可以使用await关键字来等待异步操作完成。tokio::time::sleep(duration).await;: 这是Tokio提供的异步sleep函数。它会使当前异步任务暂停执行指定的duration时间(在本例中是1秒)。await关键字表示在这里等待sleep操作完成。这意味着当前线程不会被阻塞,而是可以去执行其他异步任务。这正是异步编程的优势所在。println!("hello");: 在sleep完成后,这行代码会在控制台输出 “hello”。
使用#[tokio::main]定义运行时
Tokio提供了一个#[tokio::main]宏来包装的main()函数,用来简化运行时的创建:
[dependencies]
tokio = {version = "^1", features = ["macros", "rt", "time"]}use std::time;
#[tokio::main(flavor = "current_thread")]
async fn main() {
let duration = time::Duration::from_secs(1);
tokio::time::sleep(duration).await;
println!("hello");
}这个宏会自动为我们完成以下工作:
- 创建一个Tokio运行时。
- 根据
flavor参数配置运行时。flavor = "current_thread"表示创建一个单线程的运行时,与之前的代码等效。如果省略flavor参数,则默认创建一个多线程的运行时。 - 将
main函数转换为一个异步函数,并使用block_on来运行它。 - 启用Tokio运行时的定时器功能,因此我们不需要再手动调用
.enable_time()。
flavor参数决定了Tokio运行时的类型:
flavor = "current_thread":创建单线程的运行时。适用于简单的例子或只需要在一个线程中运行异步代码的情况。- 不指定
flavor或使用flavor = "multi_thread"创建多线程的运行时。适用于需要并发执行大量异步任务的情况,可以充分利用多核CPU的性能。注意flavor = "multi_thread"需使用的features flag是rt-multi-thread。
标记为async 的函数或代码块将返回Future,而.await会告诉运行时我们想要等待结果。
async和.await的语法允许我们编写看起来像同步代码的异步代码,但却没有使用Future所带来的复杂性。可以将async与函数、闭包和代码块一起使用。