增加 完成量 部分.
Signed-off-by: chen.yang <chen.yang@yuzhen-iot.com>
This commit is contained in:
parent
df41b19231
commit
0489e739bd
@ -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()方式进行,不能获取就立即返回以避免阻塞。
|
||||
|
||||
### 读写信号量
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user