⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c-basic4.html

📁 vxworks相关论文
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<div class="CellBody"><a name="85051"> </a><b class="routine"><i class="routine">semDelete</i></b><b>(&nbsp;)</b> &nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="85053"> </a>Terminate and free a semaphore.&nbsp;</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="85056"> </a><b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b> &nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="85058"> </a>Take a semaphore.&nbsp;</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="85061"> </a><b class="routine"><i class="routine">semGive</i></b><b>(&nbsp;)</b> &nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="85063"> </a>Give a semaphore.&nbsp;</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="85066"> </a><b class="routine"><i class="routine">semFlush</i></b><b>(&nbsp;)</b> &nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="85068"> </a>Unblock all tasks that are waiting for a semaphore.&nbsp;</div></td></tr><tr><td colspan="20"><hr class="tablerule"></td></tr><tr valign="middle"><td colspan="20"></td></tr></table></p></p><dd><p class="Body"><a name="85073"> </a>The <b class="routine"><i class="routine">semBCreate</i></b><b>(&nbsp;)</b>, <b class="routine"><i class="routine">semMCreate</i></b><b>(&nbsp;)</b>, and <b class="routine"><i class="routine">semCCreate</i></b><b>(&nbsp;)</b><b class="routine"><i class="routine"> </i></b>routines return a semaphore ID that serves as a handle on the semaphore during subsequent use by the other semaphore-control routines. When a semaphore is created, the queue type is specified. Tasks pending on a semaphore can be queued in priority order (<b class="symbol_UC">SEM_Q_PRIORITY</b>) or in first-in first-out order (<b class="symbol_UC">SEM_Q_FIFO</b>).<b></b></p></dl></dl><dl class="margin"><dd><p class="table" callout><table border="0" cellpadding="0" cellspacing="0"><tr valign="top"><td valign="top" width="40"><br><img border="0" alt="*" src="icons/warning.gif"></td><td><hr><div class="CalloutCell"><a name="92716"><b class="symbol_UC"><font face="Helvetica, sans-serif" size="-1" class="sans">WARNING:  </font></b></a>The <b class="routine"><i class="routine">semDelete</i></b><b>(&nbsp;)</b> call terminates a semaphore and deallocates any associated memory. Take care when deleting semaphores, particularly those used for mutual exclusion, to avoid deleting a semaphore that another task still requires. Do not delete a semaphore unless the same task first succeeds in taking it.</div></td></tr><tr valign="top"><td></td><td><hr></td></tr><tr valign="middle"><td colspan="20"></td></tr></table></p callout></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85078">Binary Semaphores</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="88292"> </a>The general-purpose binary semaphore is capable of addressing the requirements of both forms of task coordination: mutual exclusion and synchronization. The binary semaphore has the least overhead associated with it, making it particularly applicable to high-performance requirements. The mutual-exclusion semaphore described in <a href="c-basic4.html#85252"><i class="title">Mutual-Exclusion Semaphores</i></a> is also a binary semaphore, but it has been optimized to address problems inherent to mutual exclusion. Alternatively, the binary semaphore can be used for mutual exclusion if the advanced features of the mutual-exclusion semaphore are deemed unnecessary.<div class="frame"><h4 class="EntityTitle"><a name="90612"><font face="Helvetica, sans-serif" size="-1" class="sans">Figure 2-9:&nbsp;&nbsp;Taking a Semaphore</font></a></h4><dl class="margin"><div class="Anchor"><a name="90651"> </a><img class="figure" border="0" src="images/c-basica6.gif"></div></dl></div> <div class="frame"><h4 class="EntityTitle"><a name="90676"><font face="Helvetica, sans-serif" size="-1" class="sans">Figure 2-10:&nbsp;&nbsp;Giving a Semaphore</font></a></h4><dl class="margin"><div class="Anchor"><a name="90716"> </a><img class="figure" border="0" src="images/c-basic0.gif"></div></dl></div></p><dd><p class="Body"><a name="85084"> </a>A binary semaphore can be viewed as a flag that is available (full) or unavailable (empty). When a task takes a binary semaphore, with <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b>, the outcome depends on whether the semaphore is available (full) or unavailable (empty) at the time of the call; see <a href="c-basic4.html#90612">Figure&nbsp;2-9</a>. If the semaphore is available (full), the semaphore becomes unavailable (empty) and the task continues executing immediately. If the semaphore is unavailable (empty), the task is put on a queue of blocked tasks and enters a state of pending on the availability of the semaphore. </p><dd><p class="Body"><a name="85131"> </a>When a task gives a binary semaphore, using <b class="routine"><i class="routine">semGive</i></b><b>(&nbsp;)</b>, the outcome also depends on whether the semaphore is available (full) or unavailable (empty) at the time of the call; see <a href="c-basic4.html#90676">Figure&nbsp;2-10</a>. If the semaphore is already available (full), giving the semaphore has no effect at all. If the semaphore is unavailable (empty) and no task is waiting to take it, then the semaphore becomes available (full). If the semaphore is unavailable (empty) and one or more tasks are pending on its availability, then the first task in the queue of blocked tasks is unblocked, and the semaphore is left unavailable (empty). </p></dl></dl><dl class="margin"><dd><font face="Helvetica, sans-serif" size="-1" class="sans"><h5 class="HU"><i><a name="85180">Mutual Exclusion</a></i></h5></font><dl class="margin"><dd><p class="Body"><a name="85181"> </a>Binary semaphores interlock access to a shared resource efficiently. Unlike disabling interrupts or preemptive locks, binary semaphores limit the scope of the mutual exclusion to only the associated resource. In this technique, a semaphore is created to guard the resource. Initially the semaphore is available (full).</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="85183">    /* includes */     #include "vxWorks.h"     #include "semLib.h"      SEM_ID semMutex;      /* Create a binary semaphore that is initially full. Tasks *     &nbsp;* blocked on semaphore wait in priority order. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/      semMutex = semBCreate (SEM_Q_PRIORITY, SEM_FULL);</a></b></pre></dl><dl class="margin"><dd><p class="Body"><a name="85192"> </a>When a task wants to access the resource, it must first take that semaphore. As long as the task keeps the semaphore, all other tasks seeking access to the resource are blocked from execution. When the task is finished with the resource, it gives back the semaphore, allowing another task to use the resource.</p><dd><p class="Body"><a name="85193"> </a>Thus all accesses to a resource requiring mutual exclusion are bracketed with <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b> and <b class="routine"><i class="routine">semGive</i></b><b>(&nbsp;)</b> pairs:</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="85194">    semTake (semMutex, WAIT_FOREVER);     .     .&nbsp;&nbsp;<i class="i">critical region, only accessible by a single task at a time</i>      .     semGive (semMutex);</a></b></pre></dl><dd><font face="Helvetica, sans-serif" size="-1" class="sans"><h5 class="HU"><i><a name="85199">Synchronization</a></i></h5></font><dl class="margin"><dd><p class="Body"><a name="85200"> </a>When used for task synchronization, a semaphore can represent a condition or event that a task is waiting for. Initially the semaphore is unavailable (empty). A task or ISR signals the occurrence of the event by giving the semaphore (see <a href="c-basic5.html#86559"><i class="title">2.5&nbsp;Interrupt Service Code</i></a> for a complete discussion of ISRs). Another task waits for the semaphore by calling <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b>. The waiting task blocks until the event occurs and the semaphore is given.</p><dd><p class="Body"><a name="85204"> </a>Note the difference in sequence between semaphores used for mutual exclusion and those used for synchronization. For mutual exclusion, the semaphore is initially full, and each task first takes, then gives back the semaphore. For synchronization, the semaphore is initially empty, and one task waits to take the semaphore given by another task.</p><dd><p class="Body"><a name="90434"> </a>In <a href="c-basic4.html#85207">Example&nbsp;2-4</a>, the <b class="routine"><i class="routine">init</i></b><b>(&nbsp;)</b> routine creates the binary semaphore, attaches an ISR to an event, and spawns a task to process the event. The routine <b class="routine"><i class="routine">task1</i></b><b>(&nbsp;)</b> runs until it calls <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b>. It remains blocked at that point until an event causes the ISR to call <b class="routine"><i class="routine">semGive</i></b><b>(&nbsp;)</b>. When the ISR completes,<b class="routine"><i class="routine"> task1</i></b><b>(&nbsp;)</b> executes to process the event. There is an advantage of handling event processing within the context of a dedicated task: less processing takes place at interrupt level, thereby reducing interrupt latency. This model of event processing is recommended for real-time applications.</p></dl></dl><h4 class="EntityTitle"><a name="85207"><font face="Helvetica, sans-serif" size="-1" class="sans">Example 2-4:&nbsp;&nbsp;Using Semaphores for Task Synchronization </font></a></h4><dl class="margin"><dl class="margin"><dd><pre class="Code"><b><a name="85208">/* This example shows the use of semaphores for task synchronization. */  /* includes */ #include "vxWorks.h" #include "semLib.h" #include "arch/<i class="textVariable">arch</i>/iv<i class="textVariable">arch</i>.h" /* replace <i class="textVariable">arch</i> with architecture type */  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\n");     ... /* process event */     }  eventInterruptSvcRout (void)     {     ...      semGive (syncSem);   /* let task 1 process event */     ...      }</a></b></pre></dl><dl class="margin"><dd><p class="Body"><a name="85249"> </a>Broadcast synchronization allows all processes that are blocked on the same semaphore to be unblocked atomically. Correct application behavior often requires a set of tasks to process an event before any task of the set has the opportunity to process further events. The routine <b class="routine"><i class="routine">semFlush</i></b><b>(&nbsp;)</b> addresses this class of synchronization problem by unblocking all tasks pended on a semaphore.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85252">Mutual-Exclusion Semaphores</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85253"> </a>The mutual-exclusion semaphore is a specialized binary semaphore designed to address issues inherent in mutual exclusion, including priority inversion, deletion safety, and recursive access to resources.</p><dd><p class="Body"><a name="85254"> </a>The fundamental behavior of the mutual-exclusion semaphore is identical to the binary semaphore, with the following exceptions:</p></dl><dl class="margin"><ul class="BulletSingle" type="disc"><li><a name="85255"> </a>It can be used only for mutual exclusion.</li></ul><ul class="BulletSingle" type="disc"><li><a name="85256"> </a>It can be given only by the task that took it.</li></ul><ul class="BulletSingle" type="disc"><li><a name="85257"> </a>It cannot be given from an ISR.</li></ul><ul class="BulletSingle" type="disc"><li><a name="85259"> </a>The <b class="routine"><i class="routine">semFlush</i></b><b>(&nbsp;)</b> operation is illegal.</li></ul></dl></dl><dl class="margin"><dd><font face="Helvetica, sans-serif" size="-1" class="sans"><h5 class="HU"><i><a name="85260">Priority Inversion</a></i></h5></font><dl class="margin"><dd><p class="Body"><a name="91033"> </a><i class="term">Priority inversion</i> arises when a higher-priority task is forced to wait an indefinite period of time for a lower-priority task to complete. Consider the scenario in <a href="c-basic4.html#91041">Figure&nbsp;2-11</a>: <b class="task">t1</b>, <b class="task">t2</b>, and <b class="task">t3</b> are tasks of high, medium, and low priority, respectively. <b class="task">t3</b> has acquired some resource by taking its associated binary guard semaphore. When <b class="task">t1</b> preempts <b class="task">t3</b> and contends for the resource by taking the same semaphore, it becomes blocked. If we could be assured that <b class="task">t1</b> would be blocked no longer than the time it normally takes <b class="task">t3</b> to finish with the resource, there would be no problem because the resource cannot be preempted. However, the low-priority task is vulnerable to preemption by medium-priority tasks (like <b class="task">t2</b>), which could inhibit <b class="task">t3</b> from relinquishing the resource. This condition could persist, blocking <b class="task">t1</b> for an indefinite period of time. <div class="frame"><h4 class="EntityTitle"><a name="91041"><font face="Helvetica, sans-serif" size="-1" class="sans">Figure 2-11:&nbsp;&nbsp;Priority Inversion</font></a></h4><dl class="margin"><div class="Anchor"><a name="91094"> </a><img class="figure" border="0" src="images/c-basic9.gif"></div></dl></div></p><dd><p class="Body"><a name="91096"> </a>The mutual-exclusion semaphore has the option <b class="symbol_UC">SEM_INVERSION_SAFE</b>, which enables a <i class="term">priority-inheritance</i> algorithm. The priority-inheritance protocol assures that a task that owns a resource executes at the priority of the highest-priority task blocked on that resource. Once the task priority has been elevated, it remains at the higher level until all mutual-exclusion semaphores that the task owns are released; then the task returns to its normal, or standard, priority. Hence, the "inheriting" task is protected from preemption by any intermediate-priority tasks. This option must be used in conjunction with a priority queue (<b class="symbol_UC">SEM_Q_PRIORITY</b>).<div class="frame"><h4 class="EntityTitle"><a name="91101"><font face="Helvetica, sans-serif" size="-1" class="sans">Figure 2-12:&nbsp;&nbsp;Priority Inheritance</font></a></h4><dl class="margin"><div class="Anchor"><a name="91135"> </a><img class="figure" border="0" src="images/c-basica7.gif"></div>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -