这tokio::sync::mutex
documentation人提到了以下几点:
与流行的看法相反,在异步代码中使用标准库中的普通Mutex是可以的,而且通常更受欢迎.
这条 comments 是由this人更详细地写出来的,所以请回答:
- 如果需要在.aWait调用上持有锁,请使用异步互斥锁.在使用线程安全的future 时,编译器通常会拒绝这一点,因为大多数同步互斥锁不能被发送到另一个线程.
- 如果你的锁是有争议的(即,如果你希望互斥锁在你需要的时候已经被锁定),你应该使用异步互斥锁.当将多个任务同步到池或有界队列中时,可能会发生这种情况.
- 如果您有复杂的和/或计算繁重的更新,则无论如何都应该将这些更新移到阻塞池中,在那里您将使用同步互斥.
在使用单线程Tokio运行时的情况下,这似乎描绘了一幅完整的画面.然而,如果使用多线程运行时,可能会出现这样的情况:OS线程1上的任务A持有同步互斥锁,并且其线程被操作系统抢占,此时线程2上的任务B可能被调度并且浪费试图获取互斥锁的周期.这对于Tokio互斥来说不是问题,因为任务B将调用await
,并且可以用不同的任务来替换.
为什么没有更多地提到同步互斥锁的这一潜在缺点呢? 与使用异步互斥锁的开销相比,这种开销来源通常微不足道吗?