2022-07-31 17:27:43 +08:00

99 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 锁的类型及其规则
## 简介
  DragonOS内核实现了一些锁大致可以分为两类
- 休眠锁
- 自旋锁
## 锁的类型
### 休眠锁
  休眠锁只能在可抢占的上下文之中被获取。
  在DragonOS之中实现了以下的休眠锁
- semaphore
- mutex_t
### 自旋锁
- spinlock_t
  进程在获取自旋锁后将改变pcb中的锁变量持有计数从而隐式地禁止了抢占。为了获得更多灵活的操作spinlock还提供了以下的方法
| 后缀 | 说明 |
| ------------------------ | -------------------------- |
| _irq() | 在加锁时关闭中断/在放锁时开启中断 |
| _irqsave()/_irqrestore() | 在加锁时保存中断状态,并关中断/在放锁时恢复中断状态 |
## 详细介绍
### semaphore信号量
  semaphore信号量是基于计数实现的。
  当可用资源不足时尝试对semaphore执行down操作的进程将会被休眠直到资源可用。
### mutex互斥量
  mutex是一种轻量级的同步原语只有0和1两种状态。
  当mutex被占用时尝试对mutex进行加锁操作的进程将会被休眠直到资源可用。
#### 特性
- 同一时间只有1个任务可以持有mutex
- 不允许递归地加锁、解锁
- 只允许通过mutex的api来操作mutex
- 在硬中断、软中断中不能使用mutex
#### 数据结构
  mutex定义在`common/mutex.h`中。其数据类型如下所示:
```c
typedef struct
{
atomic_t count; // 锁计数。1->已解锁。 0->已上锁,且有可能存在等待者
spinlock_t wait_lock; // mutex操作锁用于对mutex的list的操作进行加锁
struct List wait_list; // Mutex的等待队列
} mutex_t;
```
#### API
##### mutex_init
**`void mutex_init(mutex_t *lock)`**
  初始化一个mutex对象。
##### mutex_lock
**`void mutex_lock(mutex_t *lock)`**
  对一个mutex对象加锁。若mutex当前被其他进程持有则当前进程进入休眠状态。
##### mutex_unlock
**`void mutex_unlock(mutex_t *lock)`**
  对一个mutex对象解锁。若mutex的等待队列中有其他的进程则唤醒下一个进程。
##### mutex_trylock
**`void mutex_trylock(mutex_t *lock)`**
  尝试对一个mutex对象加锁。若mutex当前被其他进程持有则返回0.否则加锁成功返回1.
##### mutex_is_locked
**`void mutex_is_locked(mutex_t *lock)`**
  判断mutex是否已被加锁。若给定的mutex已处于上锁状态则返回1否则返回0。