在The Rust Book 的第 20 章中,构建了一个线程池的示例实现。作业通过单生产者多消费者通道传递给工作人员:每个工作人员都有一个Arc<Mutex<Receiver>>从队列中挑选工作。
工作线程主体的第一个示例如下所示:
loop {
let job = receiver.lock().unwrap().recv().unwrap();
println!("Worker {} got a job; executing.", id);
job();
}
Run Code Online (Sandbox Code Playgroud)
当我看到这个时,我的第一个想法是“但是互斥锁在job运行时被保持”(即我不希望互斥锁被释放,直到lock循环结束时的返回值超出范围)。
然而,这本书提供了第二个例子:
while let Ok(job) = receiver.lock().unwrap().recv() {
println!("Worker {} got a job; executing.", id);
job();
}
Run Code Online (Sandbox Code Playgroud)
这本书说这个例子展示了我描述的问题,即“锁在调用期间保持保持job()”。它继续说,前一个例子逃避了这个问题,因为“一旦语句结束,MutexGuard从lock方法返回的值就会被删除let job”。
最后一部分听起来好像,因为MutexGuard从来没有真正分配给变量,一旦表达式完成评估,它的生命周期就结束了。那是有道理的。但第二个例子不也是如此吗?为什么在while表达式中会改变MutexGuard值的生命周期?
迈克尔的回答基本上是正确的。更多细节可以在Rust 的关于 Place Expressions, Value Expressions 和 Temporary Lifetimes 的参考资料中找到:
在第一个示例 ( let job = ...) 中,MutexGuard是临时的。临时生命周期在语句结束时结束。因此,MutexGuard在let job = ...语句之后删除了。
在第二个示例中while let ...,MutexGuard是 -表达式的检查对象的一部分while。这使得MutexGuard位置表达式上下文中的值表达式的一部分。由于'static无法升级到 a ,整个生命周期scrutinee是封闭块,而不是封闭语句。也就是说,MutexGuard为整个while let-block持有。
| 归档时间: |
|
| 查看次数: |
424 次 |
| 最近记录: |