增加 完成量 部分.

Signed-off-by: chen.yang <chen.yang@yuzhen-iot.com>
This commit is contained in:
chen.yang 2022-04-14 09:07:42 +08:00
parent df41b19231
commit 0489e739bd
1 changed files with 28 additions and 1 deletions

View File

@ -262,7 +262,34 @@ void up(struct semaphore * sem);
如果信号量被初始化为 0则它可以用于同步同步意味着一个执行单元的继续执行需等待另一执行单元完成某事保证执行的先后顺序。
### 完成量
### 完成量completion
Linux 系统提供了一种比信号量更好的同步机制,即完成量,它用于一个执行单元等待另一个执行单元执行完某事。
```cpp
// 定义完成量。
struct completion my_completion;
// 初始化完成量。
init_completion(&my_completion);
// 定义并初始化完成量。
DECLARE_COMPLETION(my_completion);
// 等待一个 completion 被唤醒。
void wait_for_completion(struct completion *c);
// 唤醒一个等待的执行单元。
void complete(struct completion *c);
// 唤醒所有等待的执行单元。
void complete_all(struct completion *c);
```
### 自旋锁与信号量的对比
信号量是进程级的用于多个进程之间对资源的互斥虽然也是在内核中但是该内核执行路径是以进程的身份代表进程来争夺资源的。如果竞争失败会发生进程上下文切换当前进程进入睡眠状态CPU 将运行其他进程。鉴于进程上下文切换的开销也很大,因此,只有当进程占用资源时间较长时,用信号量才是较好的选择。
当所要保护的临界区访问时间比较短时,用自旋锁是非常方便的,因为它节省上下文切换的时间。但是 CPU 得不到自旋锁会在那里空转直到其他执行单元解锁为止,所以要求锁不能在临界区里长时间停留,否则会降低系统的效率。
信号量所保护的临界区可包含可能引起阻塞的代码,而自旋锁则绝对要避免用来保护包含这样代码的临界区。因为阻塞意味着要进行进程的切换,如果进程被切换出去后,另一个进程企图获取本自旋锁,死锁就会发生。
信号量存在于进程上下文,因此,如果被保护的共享资源需要在中断或软中断情况下使用,则在信号量和自旋锁之间只能选择自旋锁。当然,如果一定要使用信号量,则只能通过 down_trylock()方式进行,不能获取就立即返回以避免阻塞。
### 读写信号量