一、同步例子:
这个例子中,main函数按顺序调用 read_file1()和read_file2()函数,并打印返回的内容和相关信息。
Read_file1()函数会先睡眠4秒,然后返回内容;
Read_file2()函数会先睡眠2秒,然后返回内容。
执行程序:
可以看到程序执行后等待4秒后打印出了file 1的内容,又过了2秒才打印出file 2的内容。一共需要花费6秒钟,而我们应该可以做得更好。
二、多线程并发的例子
这次,我们为两个函数调用分别建立了一个系统线程。这次运行的速度快多了,大约在4秒多。下面我们再使用异步的方式实现一下。
三、异步的例子
想要用Rust编写异步的程序,Rust标准库只提供了一些基本的东西,这是不够的,我们需要使用第三方库。本例中,我们使用tokio这个异步运行时。
首先在Cargo.toml里添加tokio的依赖:
程序代码如下:
首先,main函数前面加了async。而且在上面加了#[tokio::main]这个注解,这会告诉编译器使用tokio作为异步运行时,这部分功能我们会在后续的文章里介绍。
read_file1()和read_file2()两个函数签名的前面加上了async,这时他们就可以变成由tokio运行时安排的异步任务了。
在第7和第10行,使用了类似创建线程的方式分别创建了两个异步任务,由tokio进行管理。而任务到底运行在当前线程还是其他线程,这依赖于tokio运行时的配置。
最后第13行,在main函数结束前,join!宏会等待两个任务结束。
让我们看看执行结果:
只打印出这一句话,说明read_file1()和read_file2()两个函数并没有执行。这是因为,这两个函数现在变成了异步函数,而异步函数是惰性的,只有遇到.await关键字才会执行。所以修改程序代码,添加await关键字:
看一下执行结果:
可以看到,这两个任务是并发执行的,这和前面的多线程类似。但不同的是这两个任务可执行在同一个线程或单独的线程,这依赖于tokio运行时的配置。
此外,也可以看到read_file2()在read_file1()完成执行,这是因为read_file2()睡了2秒而read_file1()睡了4秒。所以尽管read_file1()的任务先生成,但异步运行时先执行的是read_file2(),因为它会更早的唤醒。