# Mutex (Mutual Exclusion) — DragonOS dev 文档

备注

AI Translation Notice

This document was automatically translated by `Qwen/Qwen3-8B` model, for reference only.

- Source document: kernel/locking/mutex.md

- Translation time: 2025-05-19 01:41:16

- Translation model: `Qwen/Qwen3-8B`

Please report issues via Community Channel

备注

Author: Longjin longjin@RinGoTek.cn

# Mutex (Mutual Exclusion)

A mutex is a lightweight synchronization primitive, with only two states: locked and idle.

When a mutex is occupied, any process attempting to lock it will be put to sleep until the resource becomes available.

## 1. Features

- Only one task can hold the mutex at a time.

- Recursive locking and unlocking are not allowed.

- Mutex can only be operated through its API.

- Mutex cannot be used in hard interrupts or soft interrupts.

## 2. Definition

The mutex is defined in `lib/mutex.rs`, as shown below:

    /// @brief Mutex互斥量结构体
    /// 请注意！由于Mutex属于休眠锁，因此，如果您的代码可能在中断上下文内执行，请勿采用Mutex！
    #[derive(Debug)]
    pub struct Mutex<T> {
        /// 该Mutex保护的数据
        data: UnsafeCell<T>,
        /// Mutex内部的信息
        inner: SpinLock<MutexInner>,
    }

    #[derive(Debug)]
    struct MutexInner {
        /// 当前Mutex是否已经被上锁(上锁时，为true)
        is_locked: bool,
        /// 等待获得这个锁的进程的链表
        wait_list: LinkedList<&'static mut process_control_block>,
    }

## 3. Usage

Similar to SpinLock, the Rust version of Mutex has a guard. When using it, you need to transfer the ownership of the data to be protected to the Mutex. Moreover, the guard can only be generated after a successful lock, so at any moment, each Mutex can have at most one guard.

When you need to read or modify the data protected by the Mutex, you should first use the `lock()` method of the Mutex. This method returns a `MutexGuard`. You can use the member functions of the protected data to perform some operations, or directly read or write the protected data. (This is equivalent to obtaining a mutable reference to the protected data.)

A complete example is shown in the code below:

    let x :Mutex<Vec<i32>>= Mutex::new(Vec::new());
        {
            let mut g :MutexGuard<Vec<i32>>= x.lock();
            g.push(1);
            g.push(2);
            g.push(2);
            assert!(g.as_slice() == [1, 2, 2] || g.as_slice() == [2, 2, 1]);
            // 在此处，Mutex是加锁的状态
            debug!("x={:?}", x);
        }
        // 由于上方的变量`g`，也就是Mutex守卫的生命周期结束，自动释放了Mutex。因此，在此处，Mutex是放锁的状态
        debug!("x={:?}", x);

For variables inside a structure, we can use Mutex to perform fine-grained locking, that is, wrap the member variables that need to be locked in detail with Mutex, for example:

    pub struct a {
      pub data: Mutex<data_struct>,
    }

Of course, we can also lock the entire structure:

    struct MyStruct {
      pub data: data_struct,
    }
    /// 被全局加锁的结构体
    pub struct LockedMyStruct(Mutex<MyStruct>);

## 4. API

### 4.1. new - Initialize Mutex

#### Prototype

    pub const fn new(value: T) -> Self

#### Description

The `new()` method is used to initialize a Mutex. This method requires a protected data as a parameter. It returns a Mutex.

### 4.2. lock - Lock

#### Prototype

    pub fn lock(&self) -> MutexGuard<T>

#### Description

Lock the Mutex, returns the guard of the Mutex. You can use this guard to operate the protected data.

If the Mutex is already locked, this method will block the current process until the Mutex is released.

### 4.3. try_lock - Try to Lock

#### Prototype

    pub fn try_lock(&self) -> Result<MutexGuard<T>, i32>

#### Description

Try to lock the Mutex. If the lock fails, the current process will not be added to the waiting queue. If the lock is successful, it returns the guard of the Mutex; if the Mutex is already locked, it returns `Err(错误码)`.

## 5. C Version of Mutex (Will be deprecated in the future)

The mutex is defined in `common/mutex.h`. Its data type is as follows:

    typedef struct
    {

        atomic_t count; // 锁计数。1->已解锁。 0->已上锁,且有可能存在等待者
        spinlock_t wait_lock;   // mutex操作锁，用于对mutex的list的操作进行加锁
        struct List wait_list;  // Mutex的等待队列
    } mutex_t;

### 5.1. API

#### mutex_init

`void mutex_init(mutex_t *lock)`

Initialize a mutex object.

#### mutex_lock

`void mutex_lock(mutex_t *lock)`

Lock a mutex object. If the mutex is currently held by another process, the current process will enter a sleep state.

#### mutex_unlock

`void mutex_unlock(mutex_t *lock)`

Unlock a mutex object. If there are other processes in the mutex’s waiting queue, the next process will be awakened.

#### mutex_trylock

`void mutex_trylock(mutex_t *lock)`

Try to lock a mutex object. If the mutex is currently held by another process, it returns 0. Otherwise, the lock is successful and returns 1.

#### mutex_is_locked

`void mutex_is_locked(mutex_t *lock)`

Determine if the mutex is already locked. If the given mutex is in a locked state, it returns 1; otherwise, it returns 0.

Other Versions v: V0.4.0

Tags
  V0.1.0
  V0.1.1
  V0.1.10
  V0.1.2
  V0.1.3
  V0.1.4
  V0.1.5
  V0.1.6
  V0.1.7
  V0.1.8
  V0.1.9
  V0.2.0
  V0.3.0
  V0.4.0

Branches
  master