📄 real-time experiment #3 semaphores.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0069)http://www.rt.db.erau.edu/experiments/vx/semaphores/Experiment-3.html -->
<HTML><HEAD><TITLE>Real-Time Experiment #3: Semaphores</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2900.2873" name=GENERATOR></HEAD>
<BODY>
<CENTER>
<H1>Embry-Riddle Real-Time Laboratory Experiment<BR>Experiment #3<BR>Semaphores
</H1></CENTER>
<HR SIZE=3>
<H2>Introduction</H2>Semaphores permit multitasking applications to coordinate
their activities. The most obvious way for tasks to communicate is via various
shared data structures. Because all tasks in VxWorks exist in a single linear
address space, shared data structures between tasks is trivial. Global
variables, linear buffers, ring buffers, link lists, and pointers can be
referenced directly by code running in different context.
<P></P>However, while shared address space simplifies the exchange of data,
interlocking access to memory is crucial to avoid contention. Many methods exist
for obtaining exclusive access to resources, and one of them is semaphores.
<P></P>
<HR SIZE=3>
<H2>Objectives</H2>The following are the primary objectives of this experiment:
<UL>
<LI>To demonstrate the use of VxWorks semaphores. </LI></UL>
<P></P>
<HR SIZE=3>
<H2>Description</H2>VxWorks semaphores are highly optimized and provide the
fastest intertask communication mechanisms in VxWorks. Semaphores are the
primary means for addressing the requirements of both mutual exclusion and task
synchronization.
<P></P>The are three types of Wind semaphores, optimized to address different
classes of problems:
<P></P><EM>binary</EM>
<UL>
<LI>The fastest, most general purpose semaphore. Optimized for synchronization
and can also be used for mutual exclusion.</LI></UL>
<P></P><EM>mutual exclusion</EM>
<UL>
<LI>A special binary semaphore optimized for problems inherent in mutual
exclusion: priority inheritance, deletion safety and recursion.</LI></UL>
<P></P><EM>counting</EM>
<UL>
<LI>Like the binary semaphore, but keeps track of the number of times the
semaphore is given. Optimized for guarding multiple instances of a
resource.</LI></UL>
<P></P><B>1. Semaphore Control</B>
<P></P>Wind semaphores provide a single uniform interface for semaphore control.
Only the creation routines are specific to the semaphore type:
<UL>
<LI><EM>semBCreate(int options, SEM_B_STATE initialState ): Allocate and
intialize a binary semaphore.</EM> </LI></UL>
<P></P>
<UL>
<LI><EM>semMCreate(int options): Allocate and intialize a mutual exclusion
semaphore.</EM> </LI></UL>
<P></P>
<UL>
<LI><EM>semCCreate(int options, int initialCount): Allocate and intialize a
counting semaphore.</EM> </LI></UL>
<P></P>
<UL>
<LI><EM>semDelete(SEM_ID semId): Terminate and free a semaphore.</EM> </LI></UL>
<P></P>
<UL>
<LI><EM>semTake(SEM_ID semId, int timeout): Take a semaphore.</EM> </LI></UL>
<P></P>
<UL>
<LI><EM>semGive(SEM_ID semId): Give a semaphore.</EM> </LI></UL>
<P></P>
<UL>
<LI><EM>semFlush(SEM_ID semId): Ublock all tasks waiting for a semaphore.</EM>
</LI></UL>
<P></P>Please refer to the VxWorks Reference Manual for valid arguments in the
above routines.
<P></P><B>2. Example: Binary Semaphore</B>
<P></P>A binary semaphore can be viewed as a flag that is available or
unavailable. When a task takes a binary semaphore, using <EM>semTake()</EM>, the
outcome depends on whether the semaphore is available or unavailable at the time
of the call. If the semaphore is available, then the semaphore becomes
unavailable and then the task continues executing immediately. If the semaphore
is unavailable, the task is put on a queue of blocked tasks and enters a state
of pending on the availability of the semaphore.
<P></P>When a task gives a binary semaphore, using <EM>semGive()</EM>, the
outcome depends on whether the semaphore is available or unavailable at the time
of the call.If the semaphore is already available, giving the semaphore has no
effect at all. If the semaphore is unavailable and no task is waiting to take
it, then the semaphore becomes available. If the semaphore is unavailable and
one or more tasks are pending on its availablity, then the first task in the
queue of pending tasks is unblocked, and the semaphore is left unavailable.
<P></P>In the example below, two tasks(taskOne and taskTwo), are competing to
update the value of a global variable, called "global." The objective of the
program is to toggle the value of the global variable(1s and 0s). taskOne
changes the value of "global" to 1 and taskTwo changes the value back to 0.
<P></P>Without the use of the semaphore, the value of "global" would be random
and the value of "global" would be corrupted. <PRE>-------------------------------------------------------------------------------------
/* includes */
#include "vxWorks.h"
#include "taskLib.h"
#include "semLib.h"
#include "stdio.h"
/* function prototypes */
void taskOne(void);
void taskTwo(void);
/* globals */
#define ITER 10
SEM_ID semBinary;
int global = 0;
void binary(void)
{
int taskIdOne, taskIdTwo;
/* create semaphore with semaphore available and queue tasks on FIFO basis */
semBinary = semBCreate(SEM_Q_FIFO, SEM_FULL);
/* Note 1: lock the semaphore for scheduling purposes */
semTake(semBinary,WAIT_FOREVER);
/* spawn the two tasks */
taskIdOne = taskSpawn("t1",90,0x100,2000,(FUNCPTR)taskOne,0,0,0,0,0,0,0,0,0,0);
taskIdTwo = taskSpawn("t2",90,0x100,2000,(FUNCPTR)taskTwo,0,0,0,0,0,0,0,0,0,0);
}
void taskOne(void)
{
int i;
for (i=0; i < ITER; i++)
{
semTake(semBinary,WAIT_FOREVER); /* wait indefinitely for semaphore */
printf("I am taskOne and global = %d......................\n", ++global);
semGive(semBinary); /* give up semaphore */
}
}
void taskTwo(void)
{
int i;
semGive(semBinary); /* Note 2: give up semaphore(a scheduling fix) */
for (i=0; i < ITER; i++)
{
semTake(semBinary,WAIT_FOREVER); /* wait indefinitely for semaphore */
printf("I am taskTwo and global = %d----------------------\n", --global);
semGive(semBinary); /* give up semaphore */
}
}
-------------------------------------------------------------------------------------
</PRE>
<P></P>
<HR SIZE=3>
<H2>Procedures</H2>1. Copy the source code in the example and compile it.
<P></P>2. Load the object file onto the target machine.
<P></P>3. Run the examples by executing the main routine("binary",etc.) of the
example on WindSh terminal.
<P></P>Note: Make sure you have redirected I/O, otherwise you won't see the
results of the printf commands.
<HR SIZE=3>
<H2>Follow On Experiment</H2>Experiment 1. In the binary semaphore example,
remove the source code associated with comments Notes 1 and Notes 2. Compile and
run the program. Is there a difference in the output? Is so, explain the reasons
why.
<P></P>Experiment 2. Write a program that toggles the value of "global" between
1 and 0 using counting semaphores. Just edit the example code to make
appropriate modifications.
<P></P>
<HR SIZE=3>
<H2>Additional Information</H2>Refer to VxWorks User's Manual and Reference
Manual.
<P></P>
<HR SIZE=3>
<CENTER>
<H4><A
href="http://www.rt.db.erau.edu/experiments/vx/toc/TableOfContents.html">Return
to Primary Table of Contents </A></H4></CENTER>
<HR SIZE=3>
<CENTER>Last Updated: 16 March 1997<BR><EM>Created by: Dan Eyassu</EM><BR><A
href="mailto:eyassud@db.erau.edu">eyassud@db.erau.edu</A><BR></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -