當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Rust park用法及代碼示例


本文簡要介紹rust語言中 Function std::thread::park 的用法。

用法

pub fn park()

阻塞,除非或直到當前線程的令牌可用。

park 的調用並不能保證線程將永遠處於停放狀態,調用者應該為這種可能性做好準備。

停放和取消停放

通過 thread::park 函數和 thread::Thread::unpark 方法,每個線程都配備了一些基本的低級阻塞支持。 park 阻塞當前線程,然後可以通過在阻塞線程的句柄上調用 unpark 方法從另一個線程恢複。

從概念上講,每個 Thread 句柄都有一個關聯的標記,最初不存在:

  • std::thread::park函數會阻塞當前線程,除非或直到令牌可用於其線程句柄,此時它會自動消耗該令牌。也有可能回歸虛假地,而不消耗令牌。std::thread::park_timeout執行相同的操作,但允許指定阻塞線程的最長時間。

  • Thread 上的 unpark 方法自動使令牌可用(如果它還沒有)。因為令牌最初不存在,所以 unpark 後跟 park 將導致第二個調用立即返回。

換句話說,每個 Thread 有點像一個自旋鎖,可以使用 parkunpark 鎖定和解鎖。

請注意,被解除阻塞並不意味著與解除該線程的人有任何同步,它也可能是虛假的。例如,讓 park unpark 立即返回而不做任何事情是一種有效但低效的實現。

API 通常用於獲取當前線程的句柄,將該句柄放在共享數據結構中,以便其他線程可以找到它,然後在循環中執行 park。當滿足某些所需條件時,另一個線程在句柄上調用 unpark

這種設計的動機是雙重的:

  • 它避免了在構建新的同步原語時分配互斥鎖和條件變量的需要;線程已經提供了基本的阻塞/信號。

  • 它可以在許多平台上非常有效地實現。

例子

use std::thread;
use std::sync::{Arc, atomic::{Ordering, AtomicBool}};
use std::time::Duration;

let flag = Arc::new(AtomicBool::new(false));
let flag2 = Arc::clone(&flag);

let parked_thread = thread::spawn(move || {
    // We want to wait until the flag is set. We *could* just spin, but using
    // park/unpark is more efficient.
    while !flag2.load(Ordering::Acquire) {
        println!("Parking thread");
        thread::park();
        // We *could* get here spuriously, i.e., way before the 10ms below are over!
        // But that is no problem, we are in a loop until the flag is set anyway.
        println!("Thread unparked");
    }
    println!("Flag received");
});

// Let some time pass for the thread to be spawned.
thread::sleep(Duration::from_millis(10));

// Set the flag, and let the thread wake up.
// There is no race condition here, if `unpark`
// happens first, `park` will return immediately.
// Hence there is no risk of a deadlock.
flag.store(true, Ordering::Release);
println!("Unpark the thread");
parked_thread.thread().unpark();

parked_thread.join().unwrap();

相關用法


注:本文由純淨天空篩選整理自rust-lang.org大神的英文原創作品 Function std::thread::park。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。