上篇文章我们知道,Rust
的Future
是异步执行,await
时是阻塞在当前的异步任务task
上,直到完成。
当多个异步任务执行时,如果只能都阻塞一个个执行,那就变成同步串行执行了,当然不是我们通常希望的并发处理方式,今天就来聊聊多个异步任务的一些并发处理方式。
上篇文章我们知道,Rust
的Future
是异步执行,await
时是阻塞在当前的异步任务task
上,直到完成。
当多个异步任务执行时,如果只能都阻塞一个个执行,那就变成同步串行执行了,当然不是我们通常希望的并发处理方式,今天就来聊聊多个异步任务的一些并发处理方式。
Rust
的Future
是用来实现异步编程的。今天我们围绕其了解下Rust
的异步编程是如何构建。
Rust
用async
就能轻松创建开销很小的可异步执行的函数,在await
时其才会被调度执行。
其比较轻量级,有别于异步多线程,依托在操作系统线程之上,构建大量并发则需要大量的线程资源,对资源的消耗比较大。
比如下边用async
构建异步任务:
1 | async fn async_fn() { |
之前提到的Mutex
、Condvar
是Rust
中比较偏高层的共享数据型并发控制,更底层的并发控制也有,比如Atomic
(原子操作)。
今天结合代码来深入聊聊Atomic
及其相关的Ordering
Rust官方sync
包中提供了mpsc
模式的 (多生产者,单消费者:multi-producer, single-consumer) channel,可以实现基于消息并发控制,而不是依赖控制内存共享(加锁)。这正是go语言作者 R. Pike
所推崇的方式:
Don’t communicate by sharing memory; share memory by communicating. (R. Pike)
今天就聊聊mpsc
提供的sync_channel
和channel
。
信号量(Semaphore)是一种对资源并发访问控制的方式。
区别于互斥锁(Mutex)是对共享资源的独占访问,Semaphore允许指定多个并发访问共享资源。
就是说Semaphore像一个持有令牌(permit/token)的桶,每一个并发访问需要持有(acquire)一个令牌来访问共享资源,
当没有令牌时,没法访问共享资源,直到有新的令牌加入(add)或者原来发出的令牌放回(release)桶中。
接下来,我们尝试用通过用它来实现两个线程交替打印1和2,来更直观了解如何使用semaphore
声明:博客地址已迁移到 https://newbmiao.github.io, 原域名blog.newbmiao.com已不再使用。
不知道你有没有好奇过,Rust
是怎么控制并发安全的。为什么编译器在编译时就能发现一些并发安全的问题。
今天拿例子聊聊这背后Rust
的两个并发约束trait
:Sync
和Send
,看看它们是怎么控制并发安全的。