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

📄 c-basic4.html

📁 vxworks相关论文
💻 HTML
📖 第 1 页 / 共 5 页
字号:
</dl></div></p><dd><p class="Body"><a name="85366"> </a>In <a href="c-basic4.html#91101">Figure&nbsp;2-12</a>, priority inheritance solves the problem of priority inversion by elevating the priority of <b class="task">t3</b> to the priority of <b class="task">t1</b> during the time <b class="task">t1</b> is blocked on the semaphore. This protects <b class="task">t3</b>, and indirectly <b class="task">t1</b>, from preemption by <b class="task">t2</b>.</p><dd><p class="Body"><a name="85367"> </a>The following example creates a mutual-exclusion semaphore that uses the priority inheritance algorithm:</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="85369">    semId = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE);</a></b></pre></dl><dd><font face="Helvetica, sans-serif" size="-1" class="sans"><h5 class="HU"><i><a name="85371">Deletion Safety</a></i></h5></font><dl class="margin"><dd><p class="Body"><a name="85372"> </a>Another problem of mutual exclusion involves task deletion. Within a critical region guarded by semaphores, it is often desirable to protect the executing task from unexpected deletion. Deleting a task executing in a critical region can be catastrophic. The resource might be left in a corrupted state and the semaphore guarding the resource left unavailable, effectively preventing all access to the resource.</p><dd><p class="Body"><a name="85373"> </a>The primitives <b class="routine"><i class="routine">taskSafe</i></b><b>(&nbsp;)</b> and <b class="routine"><i class="routine">taskUnsafe</i></b><b>(&nbsp;)</b> provide one solution to task deletion. However, the mutual-exclusion semaphore offers the option <b class="symbol_UC">SEM_DELETE_SAFE</b>, which enables an implicit <b class="routine"><i class="routine">taskSafe</i></b><b>(&nbsp;)</b> with each <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b>, and a <b class="routine"><i class="routine">taskUnsafe</i></b><b>(&nbsp;)</b> with each <b class="routine"><i class="routine">semGive</i></b><b>(&nbsp;)</b>. In this way, a task can be protected from deletion while it has the semaphore. This option is more efficient than the primitives <b class="routine"><i class="routine">taskSafe</i></b><b>(&nbsp;)</b> and <b class="routine"><i class="routine">taskUnsafe</i></b><b>(&nbsp;)</b>, as the resulting code requires fewer entrances to the kernel.</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="85375">    semId = semMCreate (SEM_Q_FIFO | SEM_DELETE_SAFE);</a></b></pre></dl><dd><font face="Helvetica, sans-serif" size="-1" class="sans"><h5 class="HU"><i><a name="85376">Recursive Resource Access</a></i></h5></font><dl class="margin"><dd><p class="Body"><a name="85378"> </a>Mutual-exclusion semaphores can be taken <i class="term">recursively</i>. This means that the semaphore can be taken more than once by the task that owns it before finally being released. Recursion is useful for a set of routines that must call each other but that also require mutually exclusive access to a resource. This is possible because the system keeps track of which task currently owns the mutual-exclusion semaphore.</p><dd><p class="Body"><a name="85379"> </a>Before being released, a mutual-exclusion semaphore taken recursively must be <i class="term">given</i> the same number of times it is <i class="term">taken</i>. This is tracked by a count that increments with each <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b> and decrements with each <b class="routine"><i class="routine">semGive</i></b><b>(&nbsp;)</b>.</p></dl></dl><h4 class="EntityTitle"><a name="85381"><font face="Helvetica, sans-serif" size="-1" class="sans">Example 2-5:&nbsp;&nbsp;Recursive Use of a Mutual-Exclusion Semaphore </font></a></h4><dl class="margin"><dl class="margin"><dd><pre class="Code"><b><a name="85382">/* Function A requires access to a resource which it acquires by taking &nbsp;* mySem; function A may also need to call function B, which also  &nbsp;* requires mySem: &nbsp;*/</a></b><dd> <b><a name="85384">/* includes */ #include "vxWorks.h" #include "semLib.h" SEM_ID mySem;  /* Create a mutual-exclusion semaphore. */  init ()     {     mySem = semMCreate (SEM_Q_PRIORITY);     } funcA ()     {     semTake (mySem, WAIT_FOREVER);     printf ("funcA: Got mutual-exclusion semaphore\n");     ...      funcB ();     ...      semGive (mySem);     printf ("funcA: Released mutual-exclusion semaphore\n");     } funcB ()     {     semTake (mySem, WAIT_FOREVER);     printf ("funcB: Got mutual-exclusion semaphore\n");     ...      semGive (mySem);     printf ("funcB: Releases mutual-exclusion semaphore\n");     }</a></b></pre></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85413">Counting Semaphores</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85415"> </a>Counting semaphores are another means to implement task synchronization and mutual exclusion. The counting semaphore works like the binary semaphore except that it keeps track of the number of times a semaphore is given. Every time a semaphore is given, the count is incremented; every time a semaphore is taken, the count is decremented. When the count reaches zero, a task that tries to take the semaphore is blocked. As with the binary semaphore, if a semaphore is given and a task is blocked, it becomes unblocked. However, unlike the binary semaphore, if a semaphore is given and no tasks are blocked, then the count is incremented. This means that a semaphore that is given twice can be taken twice without blocking. <a href="c-basic4.html#91146">Table&nbsp;2-14</a> shows an example time sequence of tasks taking and giving a counting semaphore that was initialized to a count of 3.<p class="table"><h4 class="EntityTitle"><a name="91146"><font face="Helvetica, sans-serif" size="-1" class="sans">Table 2-14:&nbsp;&nbsp;Counting Semaphore Example</font></a></h4><table border="0" cellpadding="0" cellspacing="0"><tr><td colspan="20"><hr class="tablerule"></td></tr><tr valign="middle"><th rowspan="1" colspan="1"><div class="CellHeading"><b><a name="91152"> </a><font face="Helvetica, sans-serif" size="-1" class="sans">Semaphore Call</font></b></div></th><th rowspan="1" colspan="1"><div class="CellHeadingC" align="center"><a name="91154"> </a><b><font face="Helvetica, sans-serif" size="-1" class="sans">Count after Call</font></b></div></th><th rowspan="1" colspan="1"><div class="CellHeading"><b><a name="91156"> </a><font face="Helvetica, sans-serif" size="-1" class="sans">Resulting Behavior</font></b></div></th></tr><tr><td colspan="20"><hr class="tablerule2"></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="91158"> </a><b class="routine"><i class="routine">semCCreate</i></b><b>(&nbsp;)</b> &nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="91160"> </a>3</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="91162"> </a>Semaphore initialized with initial count of 3.&nbsp;</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="91164"> </a><b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b>&nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="91166"> </a>2</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="91168"> </a>Semaphore taken.&nbsp;</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="91170"> </a><b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b>&nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="91172"> </a>1</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="91174"> </a>Semaphore taken.&nbsp;</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="91176"> </a><b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b>&nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="91178"> </a>0</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="91180"> </a>Semaphore taken.&nbsp;</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="91182"> </a><b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b>&nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="91184"> </a>0</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="91186"> </a>Task blocks waiting for semaphore to be available.&nbsp;</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="91188"> </a><b class="routine"><i class="routine">semGive</i></b><b>(&nbsp;)</b>&nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="91190"> </a>0</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="91192"> </a>Task waiting is given semaphore.&nbsp;</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="91194"> </a><b class="routine"><i class="routine">semGive</i></b><b>(&nbsp;)</b>&nbsp;</div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="91196"> </a>1</div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="91198"> </a>No task waiting for semaphore; count incremented.&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="85488"> </a>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 <b class="routine"><i class="routine">semCCreate</i></b><b>(&nbsp;)</b> routine.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85489">Special Semaphore Options</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85490"> </a>The uniform Wind semaphore interface includes two special options. These options are not available for the POSIX-compatible semaphores described in <a href="c-basic4.html#85561"><i class="title">POSIX Semaphores</i></a>.</p></dl></dl><dl class="margin"><dd><font face="Helvetica, sans-serif" size="-1" class="sans"><h5 class="HU"><i><a name="85495">Timeouts</a></i></h5></font><dl class="margin"><dd><p class="Body"><a name="85496"> </a>Wind semaphores include the ability to time out from the pended state. This is controlled by a parameter to <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b> that specifies the amount of time in ticks that the task is willing to wait in the pended state. If the task succeeds in taking the semaphore within the allotted time, <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b> returns <b class="symbol_UC">OK</b>. The <b class="symbol_lc">errno</b> set when a <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b> returns <b class="symbol_UC">ERROR</b> due to timing out before successfully taking the semaphore depends upon the timeout value passed. A <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b> with <b class="symbol_UC">NO_WAIT </b>(0)<i class="term">, </i>which means<i class="term"> do not wait at all</i>, sets <b class="symbol_lc">errno</b> to <b class="symbol_UC">S_objLib_OBJ_UNAVAILABLE</b>. A <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b> with a positive timeout value returns <b class="symbol_UC">S_objLib_OBJ_TIMEOUT</b>. A timeout value of <b class="symbol_UC">WAIT_FOREVER</b> (-1) means <i class="term">wait indefinitely</i>.</p></dl><dd><font face="Helvetica, sans-serif" size="-1" class="sans"><h5 class="HU"><i><a name="85499">Queues</a></i></h5></font><dl class="margin"><dd><p class="Body"><a name="85500"> </a>Wind semaphores include the ability to select the queuing mechanism employed for tasks blocked on a semaphore. They can be queued based on either of two criteria: first-in first-out (FIFO) order, or priority order; see <a href="c-basic4.html#85555">Figure&nbsp;2-13</a>. <div class="frame"><h4 class="EntityTitle"><a name="85555"><font face="Helvetica, sans-serif" size="-1" class="sans">Figure 2-13:&nbsp;&nbsp;Task Queue Types</font></a></h4><dl class="margin"><div class="Anchor"><a name="85552"> </a><img class="figure" border="0" src="images/c-basica8.gif"></div></dl></div></p><dd><p class="Body"><a name="85556"> </a>Priority ordering better preserves the intended priority structure of the system at the expense of some overhead in <b class="routine"><i class="routine">semTake</i></b><b>(&nbsp;)</b> in sorting the tasks by priority. A FIFO queue requires no priority sorting overhead and leads to constant-time performance. The selection of queue type is specified during semaphore creation with <b class="routine"><i class="routine">semBCreate</i></b><b>(&nbsp;)</b>, <b class="routine"><i class="routine">semMCreate</i></b><b>(&nbsp;)</b>, or <b class="routine"><i class="routine">semCCreate</i></b><b>(&nbsp;)</b>. Semaphores using the priority inheritance option (<b class="symbol_UC">SEM_INVERSION_SAFE</b>) must select priority-order <b></b>queuing.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="85561">POSIX Semaphores</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="85564"> </a>POSIX defines both <i class="term">named</i> and <i class="term">unnamed</i> semaphores, which have the same properties, but use slightly different interfaces. The POSIX semaphore library provides routines for creating, opening, and destroying both named and unnamed semaphores. The POSIX semaphore routines provided by <b class="library">semPxLib </b>are shown in <a href="c-basic4.html#91283">Table&nbsp;2-15</a>. </p><dd><p class="Body"><a name="85643"> </a>With named semaphores, you assign a symbolic name<sup><a href="#foot"><b class="FootnoteMarker">1</b></a></sup> when opening the semaphore; the other named-semaphore routines accept this name as an argument.</p><dd><p class="Body"><a name="85645"> </a>The POSIX terms <i class="term">wait</i> (or <i class="term">lock</i>) and <i class="term">post</i> (or <i class="term">unlock</i>) correspond to the VxWorks terms <i class="term">take</i> and <i class="term">give</i>, respectively.</p><dd><p class="Body"><a name="91273"> </a>The initialization routine <b class="routine"><i class="routine">semPxLibInit</i></b><b>(&nbsp;)</b> is called by default when <b class="symbol_UC">INCLUDE_POSIX_SEM</b> is selected for inclusion in the project facility VxWorks view. The routines <b class="routine"><i class="routine">sem_open</i></b><b>(&nbsp;)</b>, <b class="routine"><i class="routine">sem_unlink</i></b><b>(&nbsp;)</b>, and <b class="routine"><i class="routine">sem_close</i></b><b>(&nbsp;)</b> are for opening and closing/destroying named semaphores only;<b class="routine"><i class="routine"> sem_init</i></b><b>(&nbsp;)</b> and <b class="routine"><i class="routine">sem_destroy</i></b><b>(&nbsp;)</b> are for initializing and destroying unnamed semaphores only. The routines for locking, unlocking, and getting the value of semaphores are used for both named and unnamed semaphores.<p class="table"><h4 class="EntityTitle"><a name="91283"><font face="Helvetica, sans-serif" size="-1" class="sans">Table 2-15:&nbsp;&nbsp;POSIX Semaphore Routines&nbsp;</font></a></h4>

⌨️ 快捷键说明

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