📄 c-smo2.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html><head><link rel="STYLESHEET" type="text/css" href="wrs.css"><title> Shared-Memory Objects </title></head><body bgcolor="FFFFFF"><p class="navbar" align="right"><a href="index.html"><img border="0" alt="[Contents]" src="icons/contents.gif"></a><a href="GuideIX.html"><img border="0" alt="[Index]" src="icons/index.gif"></a><a href="c-smo.html"><img border="0" alt="[Top]" src="icons/top.gif"></a><a href="c-smo1.html"><img border="0" alt="[Prev]" src="icons/prev.gif"></a><a href="c-smo3.html"><img border="0" alt="[Next]" src="icons/next.gif"></a></p><font face="Helvetica, sans-serif" class="sans"><h3 class="H2"><i><a name="84388">6.2 Using Shared-Memory Objects</a></i></h3></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84390"> </a>VxMP provides a transparent interface that makes it easy to execute code using shared-memory objects on both a multiprocessor system and a single-processor system. After an object is created, tasks can operate on shared objects with the same routines used to operate on their corresponding local objects. For example, shared semaphores, shared message queues, and shared-memory partitions have the same syntax and interface as their local counterparts. Routines such as <b class="routine"><i class="routine">semGive</i></b><b>(</b> <b>)</b>, <b class="routine"><i class="routine">semTake</i></b><b>(</b> <b>)</b>, <b class="routine"><i class="routine">msgQSend</i></b><b>(</b> <b>)</b>, <b class="routine"><i class="routine">msgQReceive</i></b><b>(</b> <b>)</b>, <b class="routine"><i class="routine">memPartAlloc</i></b><b>(</b> <b>)</b>, and <b class="routine"><i class="routine">memPartFree</i></b><b>(</b> <b>)</b> operate on both local and shared objects. Only the create routines are different. This allows an application to run in either a single-processor or a multiprocessor environment with only minor changes to system configuration, initialization, and object creation.</p><dd><p class="Body"><a name="84391"> </a>All shared-memory objects can be used on a single-processor system. This is useful for testing an application before porting it to a multiprocessor configuration. However, for objects that are used only locally, local objects always provide the best performance.</p><dd><p class="Body"><a name="84395"> </a>After the shared-memory facilities are initialized (see <a href="c-smo4.html#85343"><i class="title">6.4 Configuration</i></a> for initialization differences), all processors are treated alike. Tasks on any CPU can create and use shared-memory objects. No processor has priority over another from a shared-memory object's point of view.<sup><a href="#foot"><b class="FootnoteMarker">1</b></a></sup></p><dd><p class="Body"><a name="84399"> </a>Systems making use of shared memory can include a combination of supported architectures. This enables applications to take advantage of different processor types and still have them communicate. However, on systems where the processors have different byte ordering, you must call the macros <b class="symbol_lc">ntohl</b> and <b class="symbol_lc">htonl</b> to byte-swap the application's shared data (see <i class="title">VxWorks Network Programmer's Guide: TCP/IP Under VxWorks</i>).</p><dd><p class="Body"><a name="84403"> </a>When an object is created, an <i class="term">object ID </i>is returned to identify it. For tasks on different CPUs to access shared-memory objects, they must be able to obtain this ID. An object's ID is the same regardless of the CPU. This allows IDs to be passed using shared message queues, data structures in shared memory, or the name database.</p><dd><p class="Body"><a name="84404"> </a>Throughout the remainder of this chapter, system objects under discussion refer to shared objects unless otherwise indicated.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="84405">6.2.1 Name Database</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84407"> </a>The <b></b><i class="term">name database</i> allows the association of any value to any name, such as a shared-memory object's ID with a unique name. It can communicate or <i class="term">advertise </i>a shared-memory block's address and object type. The name database provides name-to-value and value-to-name translation, allowing objects in the database to be accessed either by name or by value. While other methods exist for advertising an object's ID, the name database is a convenient method for doing this.</p><dd><p class="Body"><a name="84409"> </a>Typically the task that creates an object also advertises the object's ID by means of the name database. By adding the new object to the database, the task associates the object's ID with a name. Tasks on other processors can look up the name in the database to get the object's ID. After the task has the ID, it can use it to access the object. </p><dd><p class="Body"><a name="84410"> </a>For example, task <b class="task">t1</b> on CPU 1 creates an object. The object ID is returned by the creation routine and entered in the name database with the name <b class="symbol_lc">myObj</b>. For task <b class="task">t2</b> on CPU 0 to operate on this object, it first finds the ID by looking up the name <b class="symbol_lc">myObj</b> in the name database. </p><dd><p class="Body"><a name="84411"> </a>This same technique can be used to advertise a shared-memory address. For example, task<b class="task"> t1</b> on CPU 0 allocates a chunk of memory and adds the address to the database with the name <b class="symbol_lc">mySharedMem</b>. Task <b class="task">t2 </b>on CPU 1 can find the address of this shared memory by looking up the address in the name database using <b class="symbol_lc">mySharedMem</b>.</p><dd><p class="Body"><a name="84412"> </a>Tasks on different processors can use an agreed-upon name to get a newly created object's value. See <a href="c-smo2.html#84419">Table 6-1</a> for a list of name service routines. Note that retrieving an ID from the name database need occur only one time for each task, and usually occurs during application initialization.<p class="table"><h4 class="EntityTitle"><a name="84419"><font face="Helvetica, sans-serif" size="-1" class="sans">Table 6-1: Name Service Routines</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="84423"> </a><font face="Helvetica, sans-serif" size="-1" class="sans">Routine</font></b></div></th><th rowspan="1" colspan="1"><div class="CellHeading"><b><a name="84425"> </a><font face="Helvetica, sans-serif" size="-1" class="sans">Functionality</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="84428"> </a><b class="routine"><i class="routine">smNameAdd</i></b><b>(</b> <b>)</b> </div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="84431"> </a>Add a name to the name database. </div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="84434"> </a><b class="routine"><i class="routine">smNameRemove</i></b><b>(</b> <b>)</b> </div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="84436"> </a>Remove a name from the name database. </div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="84439"> </a><b class="routine"><i class="routine">smNameFind</i></b><b>(</b> <b>)</b> </div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="84442"> </a>Find a shared symbol by name. </div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="84445"> </a><b class="routine"><i class="routine">smNameFindByValue</i></b><b>(</b> <b>)</b> </div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="84447"> </a>Find a shared symbol by value. </div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="84450"> </a><b class="routine"><i class="routine">smNameShow</i></b><b>(</b> <b>)</b> </div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="84452"> </a>Display the name database to the standard output device; automatically included if <b class="symbol_UC">INCLUDE_SM_OBJ</b> is selected. </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="84453"> </a>The name database service routines automatically convert to or from network-byte order; do not call <b class="routine"><i class="routine">htonl</i></b><b>( )</b>or <b class="routine"><i class="routine">ntohl</i></b><b>( )</b> explicitly for values from the name database. </p><dd><p class="Body"><a name="84496"> </a>The object types listed in <a href="c-smo2.html#84464">Table 6-2</a> are defined in <b class="file">smNameLib.h</b>.<p class="table"><h4 class="EntityTitle"><a name="84464"><font face="Helvetica, sans-serif" size="-1" class="sans">Table 6-2: Shared-Memory Object Types</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="84468"> </a><font face="Helvetica, sans-serif" size="-1" class="sans">Constant</font></b></div></th><th rowspan="1" colspan="1"><div class="CellHeadingC" align="center"><a name="84470"> </a><b><font face="Helvetica, sans-serif" size="-1" class="sans">Hex Value</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="84473"> </a><b class="symbol_UC">T_SM_SEM_B</b> </div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="84475"> </a>0</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="84478"> </a><b class="symbol_UC">T_SM_SEM_C</b> </div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="84480"> </a>1</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="84483"> </a><b class="symbol_UC">T_SM_MSG_Q</b> </div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="84485"> </a>2</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="84488"> </a><b class="symbol_UC">T_SM_PART_ID</b> </div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="84490"> </a>3</div></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="84493"> </a><b class="symbol_UC">T_SM_BLOCK</b> </div></td><td colspan=1 rowspan=1><div class="CellBodyC" align="center"><a name="84495"> </a>4</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="84498"> </a>The following example shows the name database as displayed by <b class="routine"><i class="routine">smNameShow</i></b><b>(</b> <b>)</b>, which is automatically included if <b class="symbol_UC">INCLUDE_SM_OBJ </b>is selected for inclusion in the project facility VxWorks view. The parameter to <b class="routine"><i class="routine">smNameShow</i></b><b>(</b> <b>)</b> specifies the level of information displayed; in this case, 1 indicates that all information is shown. For additional information on <b class="routine"><i class="routine">smNameShow</i></b><b>(</b> <b>)</b>, see its reference entry.</p><dl class="margin"><dd><pre class="Code2"><b><a name="84499"></b><tt class="output">-> </tt><b>smNameShow 1 </b><tt class="output">value = 0 = 0x0 </tt><b></a></b></pre></dl><dd><p class="Body"><a name="84500"> </a>The output is sent to the standard output device, and looks like the following:</p><dl class="margin"><dd><pre class="Code2"><b><a name="84501"></b><tt class="output">Name in Database Max : 100 Current : 5 Free : 95 Name Value Type ----------------- ------------- ------------- myMemory 0x3835a0 SM_BLOCK myMemPart 0x3659f9 SM_PART_ID myBuff 0x383564 SM_BLOCK mySmSemaphore 0x36431d SM_SEM_B myMsgQ 0x365899 SM_MSG_Q</tt><b> </a></b></pre></dl></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="84510">6.2.2 Shared Semaphores</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84512"> </a>Like local semaphores, <i class="term">shared semaphores</i> provide synchronization by means of atomic updates of semaphore state information. See <a href="c-basic.html#83550"><i class="title">2. Basic OS</i></a> in this manual and the reference entry for <b class="library">semLib</b> for a complete discussion of semaphores. Shared semaphores can be given and taken by tasks executing on any CPU with access to the shared memory. They can be used for either synchronization of tasks running on different CPUs or mutual exclusion for shared resources.</p><dd><p class="Body"><a name="84516"> </a>To use a shared semaphore, a task creates the semaphore and advertises its ID. This can be done by adding it to the name database. A task on any CPU in the system can use the semaphore by first getting the semaphore ID (for example, from the name database). When it has the ID, it can then take or give the semaphore. </p><dd><p class="Body"><a name="84517"> </a>In the case of employing shared semaphores for mutual exclusion, typically there is a system resource that is shared between tasks on different CPUs and the semaphore is used to prevent concurrent access. Any time a task requires exclusive access to the resource, it takes the semaphore. When the task is finished with the resource, it gives the semaphore. </p><dd><p class="Body"><a name="84518"> </a>For example, there are two tasks, <b class="task">t1</b> on CPU 0 and <b class="task">t2</b> on CPU 1. Task <b class="task">t1</b> creates the semaphore and advertises the semaphore's ID by adding it to the database and assigning the name <b class="symbol_lc">myMutexSem</b>. Task <b class="task">t2</b> looks up the name <b class="symbol_lc">myMutexSem</b> in the database to get the semaphore's ID. Whenever a task wants to access the resource, it first takes the semaphore by using the semaphore ID. When a task is done using the resource, it gives the semaphore.</p><dd><p class="Body"><a name="84519"> </a>In the case of employing shared semaphores for synchronization, assume a task on one CPU must notify a task on another CPU that some event has occurred. The task being synchronized pends on the semaphore waiting for the event to occur. When the event occurs, the task doing the synchronizing gives the semaphore.</p><dd><p class="Body"><a name="84520"> </a>For example, there are two tasks, <b class="task">t1</b> on CPU 0 and <b class="task">t2</b> on CPU 1. Both <b class="task">t1</b> and <b class="task">t2</b> are monitoring robotic arms. The robotic arm that is controlled by <b class="task">t1</b> is passing a physical object to the robotic arm controlled by<b class="task"> t2</b>. Task<b class="task"> t2</b> moves the arm into position but must then wait until<b class="task"> t1</b> indicates that it is ready for<b class="task"> t2</b> to take the object. Task<b class="task"> t1</b> creates the shared semaphore and advertises the semaphore's ID by adding it to the database and assigning the name <b class="symbol_lc">objReadySem</b>. Task <b class="task">t2</b> looks up the name <b class="symbol_lc">objReadySem</b> in the database to get the semaphore's ID. It then takes the semaphore by using the semaphore ID. If the semaphore is unavailable, <b class="task">t2</b> pends, waiting for<b class="task"> t1</b> to indicate that the object is ready for<b class="task"> t2</b>. When <b class="task">t1</b> is ready to transfer control of the object to <b class="task">t2</b>, it gives the semaphore, readying <b class="task">t2 </b>on CPU1.</p><dd><p class="Body"><a name="84521"> </a>There are two types of shared semaphores, binary and counting. Shared semaphores have their own create routines and return a <b class="symbol_UC">SEM_ID</b>. <a href="c-smo2.html#84530">Table 6-3</a> lists the create routines. All other semaphore routines, except <b class="routine"><i class="routine">semDelete</i></b><b>(</b> <b>)</b>, operate transparently on the created shared semaphore.<p class="table"><h4 class="EntityTitle"><a name="84530"><font face="Helvetica, sans-serif" size="-1" class="sans">Table 6-3: Shared Semaphore Create Routines</font></a></h4>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -