1# 与“等待”相关的api(rust语言) 2 3  如果几个进程需要等待某个事件发生,才能被运行,那么就需要一种“等待”的机制,以实现进程同步。 4 5## 1. WaitQueue等待队列 6 7   WaitQueue是一种进程同步机制,中文名为“等待队列”。它可以将当前进程挂起,并在时机成熟时,由另一个进程唤醒他们。 8 9  当您需要等待一个事件完成时,使用 WaitQueue机制能减少进程同步的开销。相比于滥用自旋锁以及信号量,或者是循环使用usleep(1000)这样的函数来完成同步, WaitQueue是一个高效的解决方案。 10 11### 1.1 WaitQueue的使用 12 13   WaitQueue的使用非常简单,只需要三步: 14 151. 初始化一个WaitQueue对象。 162. 调用这个WaitQueue的挂起相关的API,将当前进程挂起。 173. 当事件发生时,由另一个进程,调用这个WaitQueue的唤醒相关的API,唤醒一个进程。 18 19  下面是一个简单的例子: 20 21### 1.1.1 初始化一个WaitQueue对象 22 23   WaitQueue对象的初始化非常简单,只需要调用WaitQueue::INIT即可。 24 25```rust 26let mut wq = WaitQueue::INIT; 27``` 28 29### 1.1.2 挂起进程 30 31   您可以这样挂起当前进程: 32 33```rust 34wq.sleep(); 35``` 36 37   当前进程会被挂起,直到有另一个进程调用了`wq.wakeup()`。 38 39### 1.1.3 唤醒进程 40 41   您可以这样唤醒一个进程: 42 43```rust 44// 唤醒等待队列头部的进程(如果它的state & PROC_INTERRUPTIBLE 不为0) 45wq.wakeup(PROC_INTERRUPTIBLE); 46 47// 唤醒等待队列头部的进程(如果它的state & PROC_UNINTERRUPTIBLE 不为0) 48wq.wakeup(PROC_UNINTERRUPTIBLE); 49 50// 唤醒等待队列头部的进程(无论它的state是什么) 51wq.wakeup((-1) as u64); 52``` 53 54### 1.2 API 55 56### 1.2.1 挂起进程 57 58  您可以使用以下函数,将当前进程挂起,并插入到指定的等待队列。这些函数大体功能相同,只是在一些细节上有所不同。 59 60| 函数名 | 解释 | 61| --------------------------------------- | ------------------------------------------------------------- | 62| sleep() | 将当前进程挂起,并设置进程状态为PROC_INTERRUPTIBLE | 63| sleep_uninterruptible() | 将当前进程挂起,并设置进程状态为PROC_UNINTERRUPTIBLE | 64| sleep_unlock_spinlock() | 将当前进程挂起,并设置进程状态为PROC_INTERRUPTIBLE。待当前进程被插入等待队列后,解锁给定的自旋锁 | 65| sleep_unlock_mutex() | 将当前进程挂起,并设置进程状态为PROC_INTERRUPTIBLE。待当前进程被插入等待队列后,解锁给定的Mutex | 66| sleep_uninterruptible_unlock_spinlock() | 将当前进程挂起,并设置进程状态为PROC_UNINTERRUPTIBLE。待当前进程被插入等待队列后,解锁给定的自旋锁 | 67| sleep_uninterruptible_unlock_mutex() | 将当前进程挂起,并设置进程状态为PROC_UNINTERRUPTIBLE。待当前进程被插入等待队列后,解锁给定的Mutex | 68 69### 1.2.2 唤醒进程 70 71  您可以使用`wakeup(state)`函数,唤醒等待队列中的第一个进程。如果这个进程的state与给定的state进行and操作之后,结果不为0,则唤醒它。 72 73  返回值:如果有进程被唤醒,则返回true,否则返回false。 74 75### 1.2.3 其它API 76 77| 函数名 | 解释 | 78| ----- | ------------ | 79| len() | 返回等待队列中的进程数量 | 80 81 82