- 论坛徽章:
- 0
|
内核中使用的信号量用于共享资源的同步访问。有down(),up()两种类型的操作。down()用于获取资源,而up()是释放资源。一个任务想通过调用down()获取资源,而代表该资源的信号量表示“没有可用资源”的时候,进程转入等待状态,直到占有资源的进程调用up()释放资源后才能被唤醒。进程的等待与唤醒通过等待队列实现(
http://blog.chinaunix.net/u1/35101/showart_485204.html
)。1. 普通信号量:数据结构:struct semaphore { atomic_t count; int sleepers; wait_queue_head_t wait;#if WAITQUEUE_DEBUG long __magic;#endif};信号量的状态变迁 某资源有两个实例可用,因此初始化count为2。现有6个任务需要获取该资源实例,其状态变迁过程如下:-----------------------------------------------------------------------------------步骤 任务(进程) 操作 count sleepers 等待队列 描述00 initialize sema_init(sem, 2) 2 0 (NONE)01 T1 down(sem) 1 0 (NONE) T1获得一个资源实例02 T2 down(sem) 0 0 (NONE) T2获得一个资源实例03 T2 up(sem) 1 0 (NONE) T2释放一个资源实例04 T3 down(sem) 0 0 (NONE) T3获得一个资源实例05 T4 down(sem) -1 1 (T4) T4等待06 T5 down(sem) -1 1 (T4,T5) T5等待T07 T1 up(sem) -1 1 (T5) T1释放一个资源实例 T4获得一个资源实例08 T6 down(sem) -1 1 (T5,T6) T6等待09 T4 up(sem) -1 1 (T6) T4释放一个资源实例 T5获得一个资源实例10 T3 up(sem) 0 0 (NONE) T3释放一个资源实例 T6获得一个资源实例11 T5 up(sem) 1 0 (NONE) T5释放一个资源实例12 T6 up(sem) 2 0 (NONE) T6释放一个资源实例----------------------------------------------------------------------------------- 在等待队列中的任务数大于一的情况下,up()实际上会导致两次wake_up()操作。第一次是up()使sem->count自增后,sem->count-----------------------------------------------------------------------------------步骤 任务 操作 count sleepers 等待队列00 -1 1 (T1,T2...)01 Tup count++ 0 1 (T1,T2...)02 Tup __up() --> wake_up(T1) 0 1 (T1,T2...)03 T1 修改count,sleepers的值 0 0 (T1,T2...)04 T1 T1出队 0 0 (T2...)05 T1 __down() --> wake_up(T2) 0 0 (T2...)06 T1 从__down()返回 0 0 (T2...)07 T2 修改count,sleepers的值 -1 1 (T2...)08 T2 schedule() -1 1 (T2...)----------------------------------------------------------------------------------- 因此,up()释放一个资源实例,并且唤醒一个等待进程。若此时还有其它进程处于等待状态的,__down()返回前的wake_up()会暂时地唤醒等待进程,将count、sleepers再调整为(-1,1),表示暂时无足够资源提供,然后又进入等待状态。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/35101/showart_488287.html |
|