简体   繁体   English

为什么变量绑定会影响循环体内的生命周期?

[英]Why does variable binding affect lifetime inside a loop body?

In "The Rust Programming Language" in chapter 20 you go through an exercise of building a simple multi-threaded web server. 第20章的 “ Rust编程语言”中,您将练习构建一个简单的多线程Web服务器。 In the exercise you use a single std::sync::mpsc channel. 在练习中,您使用单个std::sync::mpsc通道。 The worker threads all access a single Receiver which is contained like: Arc<Mutex<mpsc::Receiver<Message>>> . 所有工作线程都访问一个包含以下内容的单个接收器: Arc<Mutex<mpsc::Receiver<Message>>>

If we write the worker thread like: 如果我们将工作线程编写为:

let thread = thread::spawn(move || loop {
    match receiver.lock().unwrap().recv().unwrap() {
        Message::NewJob(job) => {
            println!("Worker {} got a job; executing.", id);

            job.call_box();

            println!("Worker {} job complete.", id);
        }
        Message::Terminate => {
            println!("Worker {} was told to terminate.", id);

            break;
        }
    };
    println!("hello, loop");
});

Then we do not achieve concurrency, apparently the worker holds on to the mutex lock I supposed because no worker is able to pull off another job until the previous one is complete. 然后,我们就无法实现并发性, 显然该工作程序会保留我假定的互斥锁,因为在上一个工作完成之前,任何工作程序都无法完成另一个工作。 However if we simply change it to this (how the book shows the code): 但是,如果我们仅将其更改为(本书显示代码的方式):

let thread = thread::spawn(move || loop {
    let message = receiver.lock().unwrap().recv().unwrap();

    match message {
        Message::NewJob(job) => {
            println!("Worker {} got a job; executing.", id);

            job.call_box();

            println!("Worker {} job complete.", id);
        }
        Message::Terminate => {
            println!("Worker {} was told to terminate.", id);

            break;
        }
    };
    println!("hello, loop");
});

Then everything works fine. 然后一切正常。 If you fire off 5 requests you'll see each thread gets one immediately. 如果触发5个请求,您将看到每个线程立即获得一个。 Concurrency! 并发!

The question is "why does variable binding affect lifetime" (I'm assuming that's the reason). 问题是“为什么变量绑定会影响生存期”(我假设这就是原因)。 Or if not then I'm missing something and what is that?! 否则,我会丢失什么,那又是什么? The book itself talks about how you cannot implement the worker loop with while let Ok(job) = receiver.lock().unwrap().recv() { because of the scope of the lock but apparently even inside the loop there be dragons. 该书本身讨论了如何while let Ok(job) = receiver.lock().unwrap().recv() {情况下实现工人循环,由于锁的范围,但显然即使循环内部也有龙。

Because in Rust, "resource acquisition is initialization" . 因为在Rust中, “资源获取是初始化”

Specifically receiver.lock() returns a type which acquires the lock when it is initialized and releases the lock when it is dropped. 具体来说, receiver.lock()返回一种类型,该类型在初始化时获取锁,并在删除时释放锁。

In your first example, the lifetime of the MutexGuard extends to the end of the match statement, so the lock will be held while job.call_box() is called. 在您的第一个示例中, MutexGuard的生存期延长至match语句的末尾,因此在调用job.call_box()将保留该锁。

match receiver.lock().unwrap().recv().unwrap() {
    // ...
};
// `MutexGuard` is dropped and lock is released here

In your second example, the lock guard is only kept alive long enough to read a message from your message queue; 在您的第二个示例中,锁保护仅保持足够长的时间才能从您的消息队列中读取一条消息。 the lock guard is dropped at the end of the statement and the lock is released before the match is entered. 语句结尾处将放下锁保护,并在输入match之前释放锁。

let message = receiver.lock().unwrap().recv().unwrap();
// `MutexGuard` is dropped and lock is released here

match message {

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么这个变量定义意味着静态生命周期? - Why does this variable definition imply static lifetime? 变量在线程中更新,但更新后的值不反映在循环内 - Variable is updated in a thread but updated value does not reflect inside a loop 延长线程变量的生命周期 - Extend lifetime of a variable for thread 变量作用域如何影响多线程竞争条件? - How does variable scope affect multithreading race conditions? 写入器和读取器 class 中的 while 循环如何在这里工作? 线程如何改变 `empty` 变量? - How does the while loop inside writer and reader class works here ? How does the thread change the `empty` variable? 为什么在循环内调用publishProgress并多次调用(无循环)会显示不同的行为? - Why does calling publishProgress inside a loop, and calling it a number of times (without a loop), show different behavior? 为什么此锁更改对JDBC性能有很大影响? - Why does this lock change affect JDBC performance so much? 变量'runner'在循环内不更新 - Variable 'runner' is not updated inside loop pthreads 再次:为什么我的线程 function 中的 for 循环会产生溢出? - pthreads again: why does the for-loop inside my thread function generate overflow? 为什么这个程序在没有布尔条件变量的波动性的情况下不会进入无限循环? - Why this program does not go into infinite loop in absence of volatility of a boolean condition variable?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM