- UID
- 852722
|
2.3.3 关于信号量(Semaphore)
信号量(Semaphore): 信号量是解决互斥和同步协调进程最好的方法
VxWorks信号量提供最快速的任务间通信机制,它主要用于解决任务间的互斥和同步。针对不同类型的问题,有以下三种信号量:
◆ 二进制信号量(Binary) 使用最快捷、最广泛,主要用于同步或互斥;
◆ 互斥信号量(Mutual Exclusion) 特殊的二进制信号量,主要用于优先级继承、安全删除和回溯;
◆ 计数器信号量(Counting) 和二进制信号量类似,保持信号量被释放(Gaven)的次数 ,主要用于保护一个资源的多个例程(Multiple Instances Of A Resource)
信号量控制,函数介绍:
SemBCreate( ) 分配并初始化一个二进制信号量
SemMCreate( ) 分配并初始化一个互斥信号量
SemCCreate( ) 分配并初始化一个计数信号量
SemDelete( ) 终止一个自由的信号量
EmTake( ) 占有一个信号量
SemGive( ) 释放一个信号量
SemFlush( ) 解锁所有等待信号量的任务
SemBCreate( ), SemMCreate( ), And SemCCreate( )返回一个信号量ID作为其它后续任务使用该信号量的的句柄。当一个信号量被创建,它的队列(Queue)类型就被确定。等待信号量的任务队列以优先级的高低排列(SEM_Q_PRIORITY),或者一先到先得的方式排列(SEM_Q_FIFO).
当一个Semaphore创建时,指定了任务队列的种类
SemBCreat( SEM_Q_PRIORITY, SEM_FULL), SEM_Q_PRIORITY 指明处于等待状态的任务在等待队列中以优先级的顺序排列
SemBCreat(SEM_Q_FIFO,SEM_FULL), SEM_Q_FIFO指明 处于等待状态的任务在等待队列中以先进先出的顺序排列
二进制信号量(Binary)
Taking A Semaphore
Giving A Semaphore
互斥进程(Mutual Exclusion)
互斥信号量有效的内锁对共享资源的进入,与屏蔽中断(Disabling Interrupts)和优先级锁定(Preemptive Locks)相比,二进制信号量将互斥的范围限制在仅与其有关的资源上。从技术上说,创建一个信号量来保护(Guarding)资源。信号量初始化位可用的(FULL)。
当一个Semaphore创建时,指定了这个Semaphore是用在解决互斥还是用来同步任务
SemBCreat( SEM_Q_FIFO, SEM_FULL) , SEM_FULL 指明用于任务间互斥.
SEM_ID SemMutex;
SemMutex = SemBCreate (SEM_Q_PRIORITY, SEM_FULL);
当一个任务要进入资源,首先要得到一个信号量(Take That Semaphore),只要有任务在使用这个信号量,其它的要进入资源的任务要停止执行(Blocked From Execution),当这个任务完成了对资源的使用,它会释放信号量,允许另一个任务来使用资源。
SemTake (SemMutex, WAIT_FOREVER);
. . Critical Region, Only Accessible By A Single Task At A Time .
SemGive (SemMutex);
同步协调进程(Synchronization)
SemBCreat(SEM_Q_FIFO,SEM_EMPTY), SEM_EMPTY 指明用于任务间同步.
/* Includes */
#Include "VxWorks.H"
#Include "SemLib.H"
SEM_ID SyncSem;
/* ID Of Sync Semaphore */
Init ( Int SomeIntNum )
{ /* Connect Interrupt Service Routine */
IntConnect (INUM_TO_IVEC (SomeIntNum), EventInterruptSvcRout, 0);
/* Create Semaphore */
SyncSem = SemBCreate (SEM_Q_FIFO, SEM_EMPTY);
/* Spawn Task Used For Synchronization. */
TaskSpawn ("Sample", 100, 0, 20000, Task1, 0,0,0,0,0,0,0,0,0,0);
}
Task1 (Void)
{ ...
SemTake (SyncSem, WAIT_FOREVER);
/* Wait For Event To Occur */
Printf ("Task 1 Got The Semaphore ");
...
/* Process Event */
}
EventInterruptSvcRout (Void)
{ ...
SemGive (SyncSem);
/* Let Task 1 Process Event */
...
}
SemTake(SemID,Time Out)--------有Semaphore空闲,就Take, 如果没有,由Time Out 定,超时则向下执行
互斥信号量
互斥信号量是一个特殊的二进制信号量,设计用于优先级继承,安全删除和回归。
互斥信号量的使用基本和二进制信号量是类似的。但有以下不同:
仅仅被用做互斥。
只能被使用它的任务释放.(It Can Be Given Only By The Task That Took It.)
ISR 不能释放它。
不能使用函数SemFlush( )。
VxWork中的计数信号量(Counting Semaphores)
计数信号量是任务同步和互斥的另一种实现方式.计数信号量除了保留信号量被释放的次数以外和二进制信号量是一样的。每次信号量被释放(Gaven)一次,计数增加;每次信号量被占用(Taken)一次,计数减少;当计数减少为0时,要求得到信号量的任务被阻塞(Blocked)。二进制信号量是如果一个信号量被释放,有一个任务阻塞等待,则这个任务就被Unblock.而计数信号量如果一个信号量被释放,没有任务阻塞等待,则计数增加。这说明一个被释放两次的计数信号量可以被占用(Taken)两次,没有阻塞。
Counting Semaphores Are Useful For Guarding Multiple Copies Of Resources. For Example, The Use Of Five Tape Drives Might Be Coordinated Using A Counting Semaphore With An Initial Count Of 5, Or A Ring Buffer With 256 Entries Might Be Implemented Using A Counting Semaphore With An Initial Count Of 256. The Initial Count Is Specified As An Argument To The SemCCreate( ) Routine.
Counting Semaphore Example
Counting Semaphore Example
Semaphore Call
Count After Call
Resulting Behavior
SemCCreate( )
3
Semaphore Initialized With Initial Count Of 3.
SemTake( )
2
Semaphore Taken.
SemTake( )
1
Semaphore Taken.
SemTake( )
0
Semaphore Taken.
SemTake( )
0
Task Blocks Waiting For Semaphore To Be Available.
SemGive( )
0
Task Waiting Is Given Semaphore.
SemGive( )
1
No Task Waiting For Semaphore; Count Incremented. |
|