一些背景
最初,Rust從 到 切換readdir(3)到readdir_r(3)執行緒安全。但是readdir_r(3) 有一些問題,然后他們改回來了:
- Linux 和 Android:fs:在 Linux 和 Android 上使用 readdir() 而不是 readdir_r()
- Fuchsia:將 Fuchsia切換到 readdir(而不是 readdir_r)
- ...
因此,在當前的實作中,它們readdir(3)在大多數 POSIX 平臺上使用
#[cfg(any(
target_os = "android",
target_os = "linux",
target_os = "solaris",
target_os = "fuchsia",
target_os = "redox",
target_os = "illumos"
))]
fn next(&mut self) -> Option<io::Result<DirEntry>> {
unsafe {
loop {
// As of POSIX.1-2017, readdir() is not required to be thread safe; only
// readdir_r() is. However, readdir_r() cannot correctly handle platforms
// with unlimited or variable NAME_MAX. Many modern platforms guarantee
// thread safety for readdir() as long an individual DIR* is not accessed
// concurrently, which is sufficient for Rust.
super::os::set_errno(0);
let entry_ptr = readdir64(self.inner.dirp.0);
執行緒問題readdir(3)
問題readdir(3)在于它的回傳值 ( struct dirent *) 是一個指向目錄流 ( DIR) 的內部緩沖區的指標,因此可以被以下readdir(3)呼叫覆寫。因此,如果我們有一個DIR流,并與多個執行緒共享它,并且所有執行緒都在呼叫readdir(3),則可能會發生競爭條件。
如果我們想安全地處理這個問題,就需要外部同步。
我的問題
然后我很好奇 Rust 做了什么來避免這些問題。好吧,他們似乎只是呼叫readdir(3),memcpy將回傳值回傳給呼叫者分配的緩沖區,然后回傳。但是這個函式沒有標記為unsafe,這讓我很困惑。
所以我的問題是為什么呼叫fs::read_dir()多執行緒程式是安全的?
有一條評論說在 Rust 中使用它是安全的,無需額外的外部同步,但我沒有明白......
如果可以在執行緒之間共享特定的目錄流,則它需要外部同步,但我相信我們會因為缺少
&mut別名而自然地避免這種情況。DirisSync,但只能ReadDir訪問它,并且只能從其可變Iterator實作中訪問。
uj5u.com熱心網友回復:
readdir從具有相同DIR* dirp引數的多個執行緒呼叫時是不安全的(即self.inner.dirp.0在 Rust 情況下使用相同的引數),但可以使用不同dirp的 s 安全地呼叫它。由于呼叫ReadDir::next需要 a &mut self,因此可以保證沒有其他人可以在同一ReadDir實體上同時從另一個執行緒呼叫它,因此它是安全的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/520377.html
上一篇:將Volatile.Read與Interlocked.Exchange結合使用以從.NET中的多個執行緒同時訪問共享記憶體位置是否安全?
