1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
#[cfg(all(test, not(target_os = "emscripten")))]
mod tests;

use crate::cell::UnsafeCell;
use crate::fmt;
use crate::ops::{Deref, DerefMut};
use crate::sync::{poison, LockResult, TryLockError, TryLockResult};
use crate::sys_common::mutex as sys;

/// 互斥原语可用于保护共享数据
///
/// 此互斥锁将阻止等待锁可用的线程。互斥锁也可以通过 [`new`] 构造函数进行静态初始化或创建。
/// 每个互斥锁都有一个类型参数,表示它正在保护的数据。
/// 只能通过从 [`lock`] 和 [`try_lock`] 返回的 RAII 保护来访问数据,这保证了只有在互斥锁被锁定时才可以访问数据。
///
///
/// # Poisoning
///
/// 此模块中的互斥锁实现了一种称为 "poisoning" 的策略,只要线程 panics 按住互斥锁,互斥锁就会被视为中毒。
/// 一旦互斥锁中毒,默认情况下,所有其他线程都无法访问数据,因为它很可能已被污染 (某些不变性未得到维护)。
///
/// 对于互斥锁,这意味着 [`lock`] 和 [`try_lock`] 方法返回一个 [`Result`],该 [`Result`] 指示互斥锁是否已中毒。
/// 互斥锁的大多数用法将只是 [`unwrap()`] 这些结果,从而在线程之间传播 panics 以确保不会看到可能无效的不变式。
///
/// 但是,中毒的互斥锁不会阻止对底层数据的所有访问。
/// [`PoisonError`] 类型具有 [`into_inner`] 方法,该方法将返回保护,否则将在成功锁定后返回该保护。
/// 尽管锁被中毒,这仍允许访问数据。
///
/// [`new`]: Self::new
/// [`lock`]: Self::lock
/// [`try_lock`]: Self::try_lock
/// [`unwrap()`]: Result::unwrap
/// [`PoisonError`]: super::PoisonError
/// [`into_inner`]: super::PoisonError::into_inner
///
/// # Examples
///
/// ```
/// use std::sync::{Arc, Mutex};
/// use std::thread;
/// use std::sync::mpsc::channel;
///
/// const N: usize = 10;
///
/// // Spawn 几个线程用于递增共享变量 (non-atomically),并在完成所有递增操作后让主线程知道。
/////
/////
/// // 在这里,我们使用 Arc 在线程之间共享内存,并且 Arc 中的数据受到互斥锁的保护。
/////
/// let data = Arc::new(Mutex::new(0));
///
/// let (tx, rx) = channel();
/// for _ in 0..N {
///     let (data, tx) = (Arc::clone(&data), tx.clone());
///     thread::spawn(move || {
///         // 只有持有锁后,才能访问共享状态。
///         // 我们的非原子增量是安全的,因为当持有锁时,我们是唯一可以访问共享状态的线程。
/////
/////
///         // 我们用 unwrap() 的返回值来断言,我们不希望线程在持有锁的同时失败。
/////
///         let mut data = data.lock().unwrap();
///         *data += 1;
///         if *data == N {
///             tx.send(()).unwrap();
///         }
///         // `data` 离开作用域时,此处的锁已解锁。
///     });
/// }
///
/// rx.recv().unwrap();
/// ```
///
/// 要从中毒的互斥锁中恢复:
///
/// ```
/// use std::sync::{Arc, Mutex};
/// use std::thread;
///
/// let lock = Arc::new(Mutex::new(0_u32));
/// let lock2 = Arc::clone(&lock);
///
/// let _ = thread::spawn(move || -> () {
///     // 该线程将首先获取互斥锁,因为该锁尚未中毒,所以将解开 `lock` 的结果。
/////
///     let _guard = lock2.lock().unwrap();
///
///     // 按住锁 (`_guard` 在作用域中) 时,此 panic 将中毒互斥锁。
/////
///     panic!();
/// }).join();
///
/// // 到此为止,锁定都会中毒,但是可以对返回的结果进行模式匹配,以返回两个分支上的基础防护。
/////
/// let mut guard = match lock.lock() {
///     Ok(guard) => guard,
///     Err(poisoned) => poisoned.into_inner(),
/// };
///
/// *guard += 1;
/// ```
///
/// 时需要手动丢弃互斥锁守卫,以便在封闭作用域结束之前将其解锁。
///
/// ```
/// use std::sync::{Arc, Mutex};
/// use std::thread;
///
/// const N: usize = 3;
///
/// let data_mutex = Arc::new(Mutex::new(vec![1, 2, 3, 4]));
/// let res_mutex = Arc::new(Mutex::new(0));
///
/// let mut threads = Vec::with_capacity(N);
/// (0..N).for_each(|_| {
///     let data_mutex_clone = Arc::clone(&data_mutex);
///     let res_mutex_clone = Arc::clone(&res_mutex);
///
///     threads.push(thread::spawn(move || {
///         let mut data = data_mutex_clone.lock().unwrap();
///         // 这是一些重要而长期的工作的结果。
///         let result = data.iter().fold(0, |acc, x| acc + x * 2);
///         data.push(result);
///         drop(data);
///         *res_mutex_clone.lock().unwrap() += result;
///     }));
/// });
///
/// let mut data = data_mutex.lock().unwrap();
/// // 这是一些重要而长期的工作的结果。
/// let result = data.iter().fold(0, |acc, x| acc + x * 2);
/// data.push(result);
/// // 我们明确丢弃 `data`,因为不再需要 `data`,并且线程仍然有工作要做。
/// // 这允许其他线程立即开始处理数据,而无需等待其余无关工作在这里完成。
/////
/////
/// // 它在这里比在线程中更重要,因为在此之后我们对线程进行 `.join` 处理。
/// // 如果我们没有丢弃互斥锁守卫,则线程可能会永远等待它,从而导致死锁。
/////
/////
/// drop(data);
/// // 这里互斥锁防护未分配给变量,因此,即使作用域在此行之后没有结束,互斥锁仍被释放: 没有死锁。
/////
/////
/// *res_mutex.lock().unwrap() += result;
///
/// threads.into_iter().for_each(|thread| {
///     thread
///         .join()
///         .expect("The thread creating or execution failed !")
/// });
///
/// assert_eq!(*res_mutex.lock().unwrap(), 800);
/// ```
///
///
///
///
///
///
///
///
///
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "mutex_type")]
pub struct Mutex<T: ?Sized> {
    inner: sys::MovableMutex,
    poison: poison::Flag,
    data: UnsafeCell<T>,
}

// 这些是 `T: Send` 唯一重要的地方; 所有其他功能都可以在单个线程上正常运行。
//
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}

/// 互斥锁的 "scoped lock" 的 RAII 实现。
/// 当此结构体被丢弃 (离开作用域) 时,这个锁将被解锁。
///
/// 可以通过此防护程序通过其 [`Deref`] 和 [`DerefMut`] 实现来访问受互斥锁保护的数据。
///
///
/// 该结构体由 [`Mutex`] 上的 [`lock`] 和 [`try_lock`] 方法创建。
///
/// [`lock`]: Mutex::lock
/// [`try_lock`]: Mutex::try_lock
///
#[must_use = "if unused the Mutex will immediately unlock"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct MutexGuard<'a, T: ?Sized + 'a> {
    lock: &'a Mutex<T>,
    poison: poison::Guard,
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
#[stable(feature = "mutexguard", since = "1.19.0")]
unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}

impl<T> Mutex<T> {
    /// 在解锁状态下创建一个新的互斥锁,以备使用。
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Mutex;
    ///
    /// let mutex = Mutex::new(0);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new(t: T) -> Mutex<T> {
        Mutex {
            inner: sys::MovableMutex::new(),
            poison: poison::Flag::new(),
            data: UnsafeCell::new(t),
        }
    }
}

impl<T: ?Sized> Mutex<T> {
    /// 获取一个互斥锁,阻塞当前线程,直到能够这样做为止。
    ///
    /// 该函数将阻塞本地线程,直到可用于获取互斥锁为止。
    /// 返回时,该线程是唯一持有锁的线程。
    /// 返回了 RAII 守卫,以允许对锁进行一定范围的解锁。
    /// 当守卫离开作用域时,互斥锁将被解锁。
    ///
    /// 未指定将互斥锁锁定在已经持有该锁的线程中的确切行为。
    /// 但是,该函数不会在第二次调用时返回 (例如,可能为 panic 或死锁)。
    ///
    /// # Errors
    ///
    /// 如果互斥锁的另一个用户在握住互斥锁时恐慌,则一旦获取互斥锁,此调用将返回错误。
    ///
    ///
    /// # Panics
    ///
    /// 如果当前线程已锁定,则调用此函数时可能为 panic。
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::{Arc, Mutex};
    /// use std::thread;
    ///
    /// let mutex = Arc::new(Mutex::new(0));
    /// let c_mutex = Arc::clone(&mutex);
    ///
    /// thread::spawn(move || {
    ///     *c_mutex.lock().unwrap() = 10;
    /// }).join().expect("thread::spawn failed");
    /// assert_eq!(*mutex.lock().unwrap(), 10);
    /// ```
    ///
    ///
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
        unsafe {
            self.inner.raw_lock();
            MutexGuard::new(self)
        }
    }

    /// 尝试获取此锁。
    ///
    /// 如果此时无法获取锁,则返回 [`Err`]。
    /// 否则,将返回 RAII 守卫。当守卫被丢弃时,锁将被解锁。
    ///
    /// 该函数不会阻止。
    ///
    /// # Errors
    ///
    /// 如果该调用的另一个用户同时持有互斥锁,则该调用将返回 [`Poisoned`] 错误,否则将获得该调用的拒绝互锁。
    ///
    ///
    /// 如果互斥锁已被锁定而无法获取,则该调用将返回 [`WouldBlock`] 错误。
    ///
    /// [`Poisoned`]: TryLockError::Poisoned
    /// [`WouldBlock`]: TryLockError::WouldBlock
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::{Arc, Mutex};
    /// use std::thread;
    ///
    /// let mutex = Arc::new(Mutex::new(0));
    /// let c_mutex = Arc::clone(&mutex);
    ///
    /// thread::spawn(move || {
    ///     let mut lock = c_mutex.try_lock();
    ///     if let Ok(ref mut mutex) = lock {
    ///         **mutex = 10;
    ///     } else {
    ///         println!("try_lock failed");
    ///     }
    /// }).join().expect("thread::spawn failed");
    /// assert_eq!(*mutex.lock().unwrap(), 10);
    /// ```
    ///
    ///
    ///
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
        unsafe {
            if self.inner.try_lock() {
                Ok(MutexGuard::new(self)?)
            } else {
                Err(TryLockError::WouldBlock)
            }
        }
    }

    /// 立即丢弃这个守卫,从而解锁互斥锁。
    ///
    /// 此函数等效于在守卫上调用 [`drop`],但更具自记录性。
    /// 或者,守卫离开作用域时将自动丢弃。
    ///
    /// ```
    /// #![feature(mutex_unlock)]
    ///
    /// use std::sync::Mutex;
    /// let mutex = Mutex::new(0);
    ///
    /// let mut guard = mutex.lock().unwrap();
    /// *guard += 20;
    /// Mutex::unlock(guard);
    /// ```
    #[unstable(feature = "mutex_unlock", issue = "81872")]
    pub fn unlock(guard: MutexGuard<'_, T>) {
        drop(guard);
    }

    /// 确定互斥锁是否中毒。
    ///
    /// 如果另一个线程处于活动状态,则互斥锁仍可随时中毒。
    /// 如果没有其他同步,则不应信任 `false` 值来确保程序正确性。
    ///
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::{Arc, Mutex};
    /// use std::thread;
    ///
    /// let mutex = Arc::new(Mutex::new(0));
    /// let c_mutex = Arc::clone(&mutex);
    ///
    /// let _ = thread::spawn(move || {
    ///     let _lock = c_mutex.lock().unwrap();
    ///     panic!(); // 互斥锁中毒
    /// }).join();
    /// assert_eq!(mutex.is_poisoned(), true);
    /// ```
    #[inline]
    #[stable(feature = "sync_poison", since = "1.2.0")]
    pub fn is_poisoned(&self) -> bool {
        self.poison.get()
    }

    /// 使用此互斥锁,返回基础数据。
    ///
    /// # Errors
    ///
    /// 如果此互斥锁的另一个用户在按住互斥锁时恐慌,则此调用将返回错误。
    ///
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Mutex;
    ///
    /// let mutex = Mutex::new(0);
    /// assert_eq!(mutex.into_inner().unwrap(), 0);
    /// ```
    #[stable(feature = "mutex_into_inner", since = "1.6.0")]
    pub fn into_inner(self) -> LockResult<T>
    where
        T: Sized,
    {
        let data = self.data.into_inner();
        poison::map_result(self.poison.borrow(), |_| data)
    }

    /// 返回对基础数据的可变引用。
    ///
    /// 由于此调用借用 `Mutex` 是可变的,因此不需要进行实际的锁定 - 可变借用可以静态地保证不存在任何锁定。
    ///
    ///
    /// # Errors
    ///
    /// 如果此互斥锁的另一个用户在按住互斥锁时恐慌,则此调用将返回错误。
    ///
    /// # Examples
    ///
    /// ```
    /// use std::sync::Mutex;
    ///
    /// let mut mutex = Mutex::new(0);
    /// *mutex.get_mut().unwrap() = 10;
    /// assert_eq!(*mutex.lock().unwrap(), 10);
    /// ```
    ///
    #[stable(feature = "mutex_get_mut", since = "1.6.0")]
    pub fn get_mut(&mut self) -> LockResult<&mut T> {
        let data = self.data.get_mut();
        poison::map_result(self.poison.borrow(), |_| data)
    }
}

#[stable(feature = "mutex_from", since = "1.24.0")]
impl<T> From<T> for Mutex<T> {
    /// 在解锁状态下创建一个新的互斥锁,以备使用。
    /// 这等效于 [`Mutex::new`]。
    fn from(t: T) -> Self {
        Mutex::new(t)
    }
}

#[stable(feature = "mutex_default", since = "1.10.0")]
impl<T: ?Sized + Default> Default for Mutex<T> {
    /// 创建一个 `Mutex<T>`,其 T 值为 `Default`。
    fn default() -> Mutex<T> {
        Mutex::new(Default::default())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut d = f.debug_struct("Mutex");
        match self.try_lock() {
            Ok(guard) => {
                d.field("data", &&*guard);
            }
            Err(TryLockError::Poisoned(err)) => {
                d.field("data", &&**err.get_ref());
            }
            Err(TryLockError::WouldBlock) => {
                struct LockedPlaceholder;
                impl fmt::Debug for LockedPlaceholder {
                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                        f.write_str("<locked>")
                    }
                }
                d.field("data", &LockedPlaceholder);
            }
        }
        d.field("poisoned", &self.poison.get());
        d.finish_non_exhaustive()
    }
}

impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
    unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
        poison::map_result(lock.poison.borrow(), |guard| MutexGuard { lock, poison: guard })
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for MutexGuard<'_, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.lock.data.get() }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.lock.data.get() }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Drop for MutexGuard<'_, T> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            self.lock.poison.done(&self.poison);
            self.lock.inner.raw_unlock();
        }
    }
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

#[stable(feature = "std_guard_impls", since = "1.20.0")]
impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        (**self).fmt(f)
    }
}

pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::MovableMutex {
    &guard.lock.inner
}

pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
    &guard.lock.poison
}