[12] | 1 | <?xml version="1.0" encoding="utf-8"?> |
---|
| 2 | <!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" |
---|
| 3 | "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [ |
---|
| 4 | <!ENTITY % threads.entities SYSTEM "entities.xml"> |
---|
| 5 | %threads.entities; |
---|
| 6 | ]> |
---|
| 7 | <section id="threads.concepts" last-revision="$Date: 2005/10/16 14:37:34 $"> |
---|
| 8 | <title>Concepts</title> |
---|
| 9 | |
---|
| 10 | <section id="threads.concepts.mutexes"> |
---|
| 11 | <title>Mutexes</title> |
---|
| 12 | |
---|
| 13 | <note>Certain changes to the mutexes and lock concepts are |
---|
| 14 | currently under discussion. In particular, the combination of |
---|
| 15 | the multiple lock concepts into a single lock concept |
---|
| 16 | is likely, and the combination of the multiple mutex |
---|
| 17 | concepts into a single mutex concept is also possible.</note> |
---|
| 18 | |
---|
| 19 | <para>A mutex (short for mutual-exclusion) object is used to serialize |
---|
| 20 | access to a resource shared between multiple threads. The |
---|
| 21 | <link linkend="threads.concepts.Mutex">Mutex</link> concept, with |
---|
| 22 | <link linkend="threads.concepts.TryMutex">TryMutex</link> and |
---|
| 23 | <link linkend="threads.concepts.TimedMutex">TimedMutex</link> refinements, |
---|
| 24 | formalize the requirements. A model that implements Mutex and its |
---|
| 25 | refinements has two states: <emphasis role="bold">locked</emphasis> and |
---|
| 26 | <emphasis role="bold">unlocked</emphasis>. Before using a shared resource, a |
---|
| 27 | thread locks a &Boost.Threads; mutex object |
---|
| 28 | (an object whose type is a model of |
---|
| 29 | <link linkend="threads.concepts.Mutex">Mutex</link> or one of it's |
---|
| 30 | refinements), ensuring |
---|
| 31 | <link linkend="threads.glossary.thread-safe">thread-safe</link> access to |
---|
| 32 | the shared resource. When use of the shared resource is complete, the thread |
---|
| 33 | unlocks the mutex object, allowing another thread to acquire the lock and |
---|
| 34 | use the shared resource.</para> |
---|
| 35 | <para>Traditional C thread APIs, like POSIX threads or the Windows thread |
---|
| 36 | APIs, expose functions to lock and unlock a mutex object. This is dangerous |
---|
| 37 | since it's easy to forget to unlock a locked mutex. When the flow of control |
---|
| 38 | is complex, with multiple return points, the likelihood of forgetting to |
---|
| 39 | unlock a mutex object becomes even greater. When exceptions are thrown, |
---|
| 40 | it becomes nearly impossible to ensure that the mutex object is unlocked |
---|
| 41 | properly when using these traditional API's. The result is |
---|
| 42 | <link linkend="threads.glossary.deadlock">deadlock</link>.</para> |
---|
| 43 | <para>Many C++ threading libraries use a pattern known as <emphasis>Scoped |
---|
| 44 | Locking</emphasis> &cite.SchmidtStalRohnertBuschmann; to free the programmer from |
---|
| 45 | the need to explicitly lock and unlock mutex objects. With this pattern, a |
---|
| 46 | <link linkend="threads.concepts.lock-concepts">Lock</link> concept is employed where |
---|
| 47 | the lock object's constructor locks the associated mutex object and the |
---|
| 48 | destructor automatically does the unlocking. The |
---|
| 49 | &Boost.Threads; library takes this pattern to |
---|
| 50 | the extreme in that Lock concepts are the only way to lock and unlock a |
---|
| 51 | mutex object: lock and unlock functions are not exposed by any |
---|
| 52 | &Boost.Threads; mutex objects. This helps to |
---|
| 53 | ensure safe usage patterns, especially when code throws exceptions.</para> |
---|
| 54 | |
---|
| 55 | <section id="threads.concepts.locking-strategies"> |
---|
| 56 | <title>Locking Strategies</title> |
---|
| 57 | |
---|
| 58 | <para>Every mutex object follows one of several locking strategies. These |
---|
| 59 | strategies define the semantics for the locking operation when the calling |
---|
| 60 | thread already owns a lock on the mutex object.</para> |
---|
| 61 | |
---|
| 62 | <section id="threads.concepts.recursive-locking-strategy"> |
---|
| 63 | <title>Recursive Locking Strategy</title> |
---|
| 64 | |
---|
| 65 | <para>With a recursive locking strategy, when a thread attempts to acquire |
---|
| 66 | a lock on the mutex object for which it already owns a lock, the operation |
---|
| 67 | is successful. Note the distinction between a thread, which may have |
---|
| 68 | multiple locks outstanding on a recursive mutex object, and a lock object, |
---|
| 69 | which even for a recursive mutex object cannot have any of its lock |
---|
| 70 | functions called multiple times without first calling unlock.</para> |
---|
| 71 | |
---|
| 72 | <para>Internally a lock count is maintained and the owning thread must |
---|
| 73 | unlock the mutex object the same number of times that it locked it before |
---|
| 74 | the mutex object's state returns to unlocked. Since mutex objects in |
---|
| 75 | &Boost.Threads; expose locking |
---|
| 76 | functionality only through lock concepts, a thread will always unlock a |
---|
| 77 | mutex object the same number of times that it locked it. This helps to |
---|
| 78 | eliminate a whole set of errors typically found in traditional C style |
---|
| 79 | thread APIs.</para> |
---|
| 80 | |
---|
| 81 | <para>Classes <classname>boost::recursive_mutex</classname>, |
---|
| 82 | <classname>boost::recursive_try_mutex</classname> and |
---|
| 83 | <classname>boost::recursive_timed_mutex</classname> use this locking |
---|
| 84 | strategy.</para> |
---|
| 85 | </section> |
---|
| 86 | |
---|
| 87 | <section id="threads.concepts.checked-locking-strategy"> |
---|
| 88 | <title>Checked Locking Strategy</title> |
---|
| 89 | |
---|
| 90 | <para>With a checked locking strategy, when a thread attempts to acquire a |
---|
| 91 | lock on the mutex object for which the thread already owns a lock, the |
---|
| 92 | operation will fail with some sort of error indication. Further, attempts |
---|
| 93 | by a thread to unlock a mutex object that was not locked by the thread |
---|
| 94 | will also return some sort of error indication. In |
---|
| 95 | &Boost.Threads;, an exception of type |
---|
| 96 | <classname>boost::lock_error</classname> |
---|
| 97 | would be thrown in these cases.</para> |
---|
| 98 | |
---|
| 99 | <para>&Boost.Threads; does not currently |
---|
| 100 | provide any mutex objects that use this strategy.</para> |
---|
| 101 | </section> |
---|
| 102 | |
---|
| 103 | <section id="threads.concepts.unchecked-locking-strategy"> |
---|
| 104 | <title>Unchecked Locking Strategy</title> |
---|
| 105 | |
---|
| 106 | <para>With an unchecked locking strategy, when a thread attempts to acquire |
---|
| 107 | a lock on a mutex object for which the thread already owns a lock the |
---|
| 108 | operation will |
---|
| 109 | <link linkend="threads.glossary.deadlock">deadlock</link>. In general |
---|
| 110 | this locking strategy is less safe than a checked or recursive strategy, |
---|
| 111 | but it's also a faster strategy and so is employed by many libraries.</para> |
---|
| 112 | |
---|
| 113 | <para>&Boost.Threads; does not currently |
---|
| 114 | provide any mutex objects that use this strategy.</para> |
---|
| 115 | </section> |
---|
| 116 | |
---|
| 117 | <section id="threads.concepts.unspecified-locking-strategy"> |
---|
| 118 | <title>Unspecified Locking Strategy</title> |
---|
| 119 | |
---|
| 120 | <para>With an unspecified locking strategy, when a thread attempts to |
---|
| 121 | acquire a lock on a mutex object for which the thread already owns a lock |
---|
| 122 | the operation results in |
---|
| 123 | <link linkend="threads.glossary.undefined-behavior">undefined behavior</link>. |
---|
| 124 | </para> |
---|
| 125 | |
---|
| 126 | <para>In general a mutex object with an unspecified locking strategy is |
---|
| 127 | unsafe, and it requires programmer discipline to use the mutex object |
---|
| 128 | properly. However, this strategy allows an implementation to be as fast as |
---|
| 129 | possible with no restrictions on its implementation. This is especially |
---|
| 130 | true for portable implementations that wrap the native threading support |
---|
| 131 | of a platform. For this reason, the classes |
---|
| 132 | <classname>boost::mutex</classname>, |
---|
| 133 | <classname>boost::try_mutex</classname> and |
---|
| 134 | <classname>boost::timed_mutex</classname> use this locking strategy |
---|
| 135 | despite the lack of safety.</para> |
---|
| 136 | </section> |
---|
| 137 | </section> |
---|
| 138 | |
---|
| 139 | <section id="threads.concepts.sheduling-policies"> |
---|
| 140 | <title>Scheduling Policies</title> |
---|
| 141 | |
---|
| 142 | <para>Every mutex object follows one of several scheduling policies. These |
---|
| 143 | policies define the semantics when the mutex object is unlocked and there is |
---|
| 144 | more than one thread waiting to acquire a lock. In other words, the policy |
---|
| 145 | defines which waiting thread shall acquire the lock.</para> |
---|
| 146 | |
---|
| 147 | <section id="threads.concepts.FIFO-scheduling-policy"> |
---|
| 148 | <title>FIFO Scheduling Policy</title> |
---|
| 149 | |
---|
| 150 | <para>With a FIFO ("First In First Out") scheduling policy, threads waiting |
---|
| 151 | for the lock will acquire it in a first-come-first-served order. |
---|
| 152 | This can help prevent a high priority thread from starving lower priority |
---|
| 153 | threads that are also waiting on the mutex object's lock.</para> |
---|
| 154 | </section> |
---|
| 155 | |
---|
| 156 | <section id="threads.concepts.priority-driven-scheduling-policy"> |
---|
| 157 | <title>Priority Driven Policy</title> |
---|
| 158 | |
---|
| 159 | <para>With a Priority Driven scheduling policy, the thread with the |
---|
| 160 | highest priority acquires the lock. Note that this means that low-priority |
---|
| 161 | threads may never acquire the lock if the mutex object has high contention |
---|
| 162 | and there is always at least one high-priority thread waiting. This is |
---|
| 163 | known as thread starvation. When multiple threads of the same priority are |
---|
| 164 | waiting on the mutex object's lock one of the other scheduling priorities |
---|
| 165 | will determine which thread shall acquire the lock.</para> |
---|
| 166 | </section> |
---|
| 167 | |
---|
| 168 | <section id="threads.concepts.unspecified-scheduling-policy"> |
---|
| 169 | <title>Unspecified Policy</title> |
---|
| 170 | |
---|
| 171 | <para>The mutex object does not specify a scheduling policy. In order to |
---|
| 172 | ensure portability, all &Boost.Threads; |
---|
| 173 | mutex objects use an unspecified scheduling policy.</para> |
---|
| 174 | </section> |
---|
| 175 | </section> |
---|
| 176 | |
---|
| 177 | <section id="threads.concepts.mutex-concepts"> |
---|
| 178 | <title>Mutex Concepts</title> |
---|
| 179 | |
---|
| 180 | <section id="threads.concepts.Mutex"> |
---|
| 181 | <title>Mutex Concept</title> |
---|
| 182 | |
---|
| 183 | <para>A Mutex object has two states: locked and unlocked. Mutex object |
---|
| 184 | state can only be determined by a lock object meeting the |
---|
| 185 | appropriate lock concept requirements |
---|
| 186 | and constructed for the Mutex object.</para> |
---|
| 187 | |
---|
| 188 | <para>A Mutex is |
---|
| 189 | <ulink url="../../libs/utility/utility.htm#Class%20noncopyable"> |
---|
| 190 | NonCopyable</ulink>.</para> |
---|
| 191 | <para>For a Mutex type <code>M</code> |
---|
| 192 | and an object <code>m</code> of that type, |
---|
| 193 | the following expressions must be well-formed |
---|
| 194 | and have the indicated effects.</para> |
---|
| 195 | |
---|
| 196 | <table> |
---|
| 197 | <title>Mutex Expressions</title> |
---|
| 198 | |
---|
| 199 | <tgroup cols="2"> |
---|
| 200 | <thead> |
---|
| 201 | <row> |
---|
| 202 | <entry>Expression</entry> |
---|
| 203 | <entry>Effects</entry> |
---|
| 204 | </row> |
---|
| 205 | </thead> |
---|
| 206 | |
---|
| 207 | <tbody> |
---|
| 208 | <row> |
---|
| 209 | <entry>M m;</entry> |
---|
| 210 | <entry><para>Constructs a mutex object m.</para> |
---|
| 211 | <para>Postcondition: m is unlocked.</para></entry> |
---|
| 212 | </row> |
---|
| 213 | <row> |
---|
| 214 | <entry>(&m)->~M();</entry> |
---|
| 215 | <entry>Precondition: m is unlocked. Destroys a mutex object |
---|
| 216 | m.</entry> |
---|
| 217 | </row> |
---|
| 218 | <row> |
---|
| 219 | <entry>M::scoped_lock</entry> |
---|
| 220 | <entry>A model of |
---|
| 221 | <link linkend="threads.concepts.ScopedLock">ScopedLock</link> |
---|
| 222 | </entry> |
---|
| 223 | </row> |
---|
| 224 | </tbody> |
---|
| 225 | </tgroup> |
---|
| 226 | </table> |
---|
| 227 | </section> |
---|
| 228 | |
---|
| 229 | <section id="threads.concepts.TryMutex"> |
---|
| 230 | <title>TryMutex Concept</title> |
---|
| 231 | |
---|
| 232 | <para>A TryMutex is a refinement of |
---|
| 233 | <link linkend="threads.concepts.Mutex">Mutex</link>. |
---|
| 234 | For a TryMutex type <code>M</code> |
---|
| 235 | and an object <code>m</code> of that type, |
---|
| 236 | the following expressions must be well-formed |
---|
| 237 | and have the indicated effects.</para> |
---|
| 238 | |
---|
| 239 | <table> |
---|
| 240 | <title>TryMutex Expressions</title> |
---|
| 241 | |
---|
| 242 | <tgroup cols="2"> |
---|
| 243 | <thead> |
---|
| 244 | <row> |
---|
| 245 | <entry>Expression</entry> |
---|
| 246 | <entry>Effects</entry> |
---|
| 247 | </row> |
---|
| 248 | </thead> |
---|
| 249 | |
---|
| 250 | <tbody> |
---|
| 251 | <row> |
---|
| 252 | <entry>M::scoped_try_lock</entry> |
---|
| 253 | <entry>A model of |
---|
| 254 | <link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link> |
---|
| 255 | </entry> |
---|
| 256 | </row> |
---|
| 257 | </tbody> |
---|
| 258 | </tgroup> |
---|
| 259 | </table> |
---|
| 260 | </section> |
---|
| 261 | |
---|
| 262 | <section id="threads.concepts.TimedMutex"> |
---|
| 263 | <title>TimedMutex Concept</title> |
---|
| 264 | |
---|
| 265 | <para>A TimedMutex is a refinement of |
---|
| 266 | <link linkend="threads.concepts.TryMutex">TryMutex</link>. |
---|
| 267 | For a TimedMutex type <code>M</code> |
---|
| 268 | and an object <code>m</code> of that type, |
---|
| 269 | the following expressions must be well-formed |
---|
| 270 | and have the indicated effects.</para> |
---|
| 271 | |
---|
| 272 | <table> |
---|
| 273 | <title>TimedMutex Expressions</title> |
---|
| 274 | |
---|
| 275 | <tgroup cols="2"> |
---|
| 276 | <thead> |
---|
| 277 | <row> |
---|
| 278 | <entry>Expression</entry> |
---|
| 279 | <entry>Effects</entry> |
---|
| 280 | </row> |
---|
| 281 | </thead> |
---|
| 282 | |
---|
| 283 | <tbody> |
---|
| 284 | <row> |
---|
| 285 | <entry>M::scoped_timed_lock</entry> |
---|
| 286 | <entry>A model of |
---|
| 287 | <link |
---|
| 288 | linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link> |
---|
| 289 | </entry> |
---|
| 290 | </row> |
---|
| 291 | </tbody> |
---|
| 292 | </tgroup> |
---|
| 293 | </table> |
---|
| 294 | </section> |
---|
| 295 | </section> |
---|
| 296 | |
---|
| 297 | <section id="threads.concepts.mutex-models"> |
---|
| 298 | <title>Mutex Models</title> |
---|
| 299 | |
---|
| 300 | <para>&Boost.Threads; currently supplies six models of |
---|
| 301 | <link linkend="threads.concepts.Mutex">Mutex</link> |
---|
| 302 | and its refinements.</para> |
---|
| 303 | |
---|
| 304 | <table> |
---|
| 305 | <title>Mutex Models</title> |
---|
| 306 | |
---|
| 307 | <tgroup cols="3"> |
---|
| 308 | <thead> |
---|
| 309 | <row> |
---|
| 310 | <entry>Concept</entry> |
---|
| 311 | <entry>Refines</entry> |
---|
| 312 | <entry>Models</entry> |
---|
| 313 | </row> |
---|
| 314 | </thead> |
---|
| 315 | |
---|
| 316 | <tbody> |
---|
| 317 | <row> |
---|
| 318 | <entry><link linkend="threads.concepts.Mutex">Mutex</link></entry> |
---|
| 319 | <entry></entry> |
---|
| 320 | <entry> |
---|
| 321 | <para><classname>boost::mutex</classname></para> |
---|
| 322 | <para><classname>boost::recursive_mutex</classname></para> |
---|
| 323 | </entry> |
---|
| 324 | </row> |
---|
| 325 | <row> |
---|
| 326 | <entry><link linkend="threads.concepts.TryMutex">TryMutex</link></entry> |
---|
| 327 | <entry><link linkend="threads.concepts.Mutex">Mutex</link></entry> |
---|
| 328 | <entry> |
---|
| 329 | <para><classname>boost::try_mutex</classname></para> |
---|
| 330 | <para><classname>boost::recursive_try_mutex</classname></para> |
---|
| 331 | </entry> |
---|
| 332 | </row> |
---|
| 333 | <row> |
---|
| 334 | <entry><link linkend="threads.concepts.TimedMutex">TimedMutex</link></entry> |
---|
| 335 | <entry><link linkend="threads.concepts.TryMutex">TryMutex</link></entry> |
---|
| 336 | <entry> |
---|
| 337 | <para><classname>boost::timed_mutex</classname></para> |
---|
| 338 | <para><classname>boost::recursive_timed_mutex</classname></para> |
---|
| 339 | </entry> |
---|
| 340 | </row> |
---|
| 341 | </tbody> |
---|
| 342 | </tgroup> |
---|
| 343 | </table> |
---|
| 344 | </section> |
---|
| 345 | |
---|
| 346 | <section id="threads.concepts.lock-concepts"> |
---|
| 347 | <title>Lock Concepts</title> |
---|
| 348 | |
---|
| 349 | <para>A lock object provides a safe means for locking and unlocking a mutex |
---|
| 350 | object (an object whose type is a model of <link |
---|
| 351 | linkend="threads.concepts.Mutex">Mutex</link> or one of its refinements). In |
---|
| 352 | other words they are an implementation of the <emphasis>Scoped |
---|
| 353 | Locking</emphasis> &cite.SchmidtStalRohnertBuschmann; pattern. The <link |
---|
| 354 | linkend="threads.concepts.ScopedLock">ScopedLock</link>, |
---|
| 355 | <link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link>, and |
---|
| 356 | <link linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link> |
---|
| 357 | concepts formalize the requirements.</para> |
---|
| 358 | <para>Lock objects are constructed with a reference to a mutex object and |
---|
| 359 | typically acquire ownership of the mutex object by setting its state to |
---|
| 360 | locked. They also ensure ownership is relinquished in the destructor. Lock |
---|
| 361 | objects also expose functions to query the lock status and to manually lock |
---|
| 362 | and unlock the mutex object.</para> |
---|
| 363 | <para>Lock objects are meant to be short lived, expected to be used at block |
---|
| 364 | scope only. The lock objects are not <link |
---|
| 365 | linkend="threads.glossary.thread-safe">thread-safe</link>. Lock objects must |
---|
| 366 | maintain state to indicate whether or not they've been locked and this state |
---|
| 367 | is not protected by any synchronization concepts. For this reason a lock |
---|
| 368 | object should never be shared between multiple threads.</para> |
---|
| 369 | |
---|
| 370 | <section id="threads.concepts.Lock"> |
---|
| 371 | <title>Lock Concept</title> |
---|
| 372 | |
---|
| 373 | <para>For a Lock type <code>L</code> |
---|
| 374 | and an object <code>lk</code> |
---|
| 375 | and const object <code>clk</code> of that type, |
---|
| 376 | the following expressions must be well-formed |
---|
| 377 | and have the indicated effects.</para> |
---|
| 378 | |
---|
| 379 | <table> |
---|
| 380 | <title>Lock Expressions</title> |
---|
| 381 | |
---|
| 382 | <tgroup cols="2"> |
---|
| 383 | <thead> |
---|
| 384 | <row> |
---|
| 385 | <entry>Expression</entry> |
---|
| 386 | <entry>Effects</entry> |
---|
| 387 | </row> |
---|
| 388 | </thead> |
---|
| 389 | |
---|
| 390 | <tbody> |
---|
| 391 | <row> |
---|
| 392 | <entry><code>(&lk)->~L();</code></entry> |
---|
| 393 | <entry><code>if (locked()) unlock();</code></entry> |
---|
| 394 | </row> |
---|
| 395 | <row> |
---|
| 396 | <entry><code>(&clk)->operator const void*()</code></entry> |
---|
| 397 | <entry>Returns type void*, non-zero if the associated mutex |
---|
| 398 | object has been locked by <code>clk</code>, otherwise 0.</entry> |
---|
| 399 | </row> |
---|
| 400 | <row> |
---|
| 401 | <entry><code>clk.locked()</code></entry> |
---|
| 402 | <entry>Returns a <code>bool</code>, <code>(&clk)->operator |
---|
| 403 | const void*() != 0</code></entry> |
---|
| 404 | </row> |
---|
| 405 | <row> |
---|
| 406 | <entry><code>lk.lock()</code></entry> |
---|
| 407 | <entry> |
---|
| 408 | <para>Throws <classname>boost::lock_error</classname> |
---|
| 409 | if <code>locked()</code>.</para> |
---|
| 410 | |
---|
| 411 | <para>If the associated mutex object is |
---|
| 412 | already locked by some other thread, places the current thread in the |
---|
| 413 | <link linkend="threads.glossary.thread-state">Blocked</link> state until |
---|
| 414 | the associated mutex is unlocked, after which the current thread |
---|
| 415 | is placed in the <link |
---|
| 416 | linkend="threads.glossary.thread-state">Ready</link> state, |
---|
| 417 | eventually to be returned to the <link |
---|
| 418 | linkend="threads.glossary.thread-state">Running</link> state. If |
---|
| 419 | the associated mutex object is already locked by the same thread |
---|
| 420 | the behavior is dependent on the <link |
---|
| 421 | linkend="threads.concepts.locking-strategies">locking |
---|
| 422 | strategy</link> of the associated mutex object.</para> |
---|
| 423 | |
---|
| 424 | <para>Postcondition: <code>locked() == true</code></para> |
---|
| 425 | </entry> |
---|
| 426 | </row> |
---|
| 427 | <row> |
---|
| 428 | <entry><code>lk.unlock()</code></entry> |
---|
| 429 | <entry> |
---|
| 430 | <para>Throws <classname>boost::lock_error</classname> |
---|
| 431 | if <code>!locked()</code>.</para> |
---|
| 432 | |
---|
| 433 | <para>Unlocks the associated mutex.</para> |
---|
| 434 | |
---|
| 435 | <para>Postcondition: <code>!locked()</code></para></entry> |
---|
| 436 | </row> |
---|
| 437 | </tbody> |
---|
| 438 | </tgroup> |
---|
| 439 | </table> |
---|
| 440 | </section> |
---|
| 441 | |
---|
| 442 | <section id="threads.concepts.ScopedLock"> |
---|
| 443 | <title>ScopedLock Concept</title> |
---|
| 444 | |
---|
| 445 | <para>A ScopedLock is a refinement of <link |
---|
| 446 | linkend="threads.concepts.Lock">Lock</link>. |
---|
| 447 | For a ScopedLock type <code>L</code> |
---|
| 448 | and an object <code>lk</code> of that type, |
---|
| 449 | and an object <code>m</code> of a type meeting the |
---|
| 450 | <link linkend="threads.concepts.Mutex">Mutex</link> requirements, |
---|
| 451 | and an object <code>b</code> of type <code>bool</code>, |
---|
| 452 | the following expressions must be well-formed |
---|
| 453 | and have the indicated effects.</para> |
---|
| 454 | |
---|
| 455 | <table> |
---|
| 456 | <title>ScopedLock Expressions</title> |
---|
| 457 | |
---|
| 458 | <tgroup cols="2"> |
---|
| 459 | <thead> |
---|
| 460 | <row> |
---|
| 461 | <entry>Expression</entry> |
---|
| 462 | <entry>Effects</entry> |
---|
| 463 | </row> |
---|
| 464 | </thead> |
---|
| 465 | |
---|
| 466 | <tbody> |
---|
| 467 | <row> |
---|
| 468 | <entry><code>L lk(m);</code></entry> |
---|
| 469 | <entry>Constructs an object <code>lk</code>, and associates mutex |
---|
| 470 | object <code>m</code> with it, then calls |
---|
| 471 | <code>lock()</code></entry> |
---|
| 472 | </row> |
---|
| 473 | <row> |
---|
| 474 | <entry><code>L lk(m,b);</code></entry> |
---|
| 475 | <entry>Constructs an object <code>lk</code>, and associates mutex |
---|
| 476 | object <code>m</code> with it, then if <code>b</code>, calls |
---|
| 477 | <code>lock()</code></entry> |
---|
| 478 | </row> |
---|
| 479 | </tbody> |
---|
| 480 | </tgroup> |
---|
| 481 | </table> |
---|
| 482 | </section> |
---|
| 483 | |
---|
| 484 | <section id="threads.concepts.TryLock"> |
---|
| 485 | <title>TryLock Concept</title> |
---|
| 486 | |
---|
| 487 | <para>A TryLock is a refinement of <link |
---|
| 488 | linkend="threads.concepts.Lock">Lock</link>. |
---|
| 489 | For a TryLock type <code>L</code> |
---|
| 490 | and an object <code>lk</code> of that type, |
---|
| 491 | the following expressions must be well-formed |
---|
| 492 | and have the indicated effects.</para> |
---|
| 493 | |
---|
| 494 | <table> |
---|
| 495 | <title>TryLock Expressions</title> |
---|
| 496 | |
---|
| 497 | <tgroup cols="2"> |
---|
| 498 | <thead> |
---|
| 499 | <row> |
---|
| 500 | <entry>Expression</entry> |
---|
| 501 | <entry>Effects</entry> |
---|
| 502 | </row> |
---|
| 503 | </thead> |
---|
| 504 | |
---|
| 505 | <tbody> |
---|
| 506 | <row> |
---|
| 507 | <entry><code>lk.try_lock()</code></entry> |
---|
| 508 | <entry> |
---|
| 509 | <para>Throws <classname>boost::lock_error</classname> |
---|
| 510 | if locked().</para> |
---|
| 511 | |
---|
| 512 | <para>Makes a |
---|
| 513 | non-blocking attempt to lock the associated mutex object, |
---|
| 514 | returning <code>true</code> if the lock attempt is successful, |
---|
| 515 | otherwise <code>false</code>. If the associated mutex object is |
---|
| 516 | already locked by the same thread the behavior is dependent on the |
---|
| 517 | <link linkend="threads.concepts.locking-strategies">locking |
---|
| 518 | strategy</link> of the associated mutex object.</para> |
---|
| 519 | </entry> |
---|
| 520 | </row> |
---|
| 521 | </tbody> |
---|
| 522 | </tgroup> |
---|
| 523 | </table> |
---|
| 524 | </section> |
---|
| 525 | |
---|
| 526 | <section id="threads.concepts.ScopedTryLock"> |
---|
| 527 | <title>ScopedTryLock Concept</title> |
---|
| 528 | |
---|
| 529 | <para>A ScopedTryLock is a refinement of <link |
---|
| 530 | linkend="threads.concepts.TryLock">TryLock</link>. |
---|
| 531 | For a ScopedTryLock type <code>L</code> |
---|
| 532 | and an object <code>lk</code> of that type, |
---|
| 533 | and an object <code>m</code> of a type meeting the |
---|
| 534 | <link linkend="threads.concepts.TryMutex">TryMutex</link> requirements, |
---|
| 535 | and an object <code>b</code> of type <code>bool</code>, |
---|
| 536 | the following expressions must be well-formed |
---|
| 537 | and have the indicated effects.</para> |
---|
| 538 | |
---|
| 539 | <table> |
---|
| 540 | <title>ScopedTryLock Expressions</title> |
---|
| 541 | |
---|
| 542 | <tgroup cols="2"> |
---|
| 543 | <thead> |
---|
| 544 | <row> |
---|
| 545 | <entry>Expression</entry> |
---|
| 546 | <entry>Effects</entry> |
---|
| 547 | </row> |
---|
| 548 | </thead> |
---|
| 549 | |
---|
| 550 | <tbody> |
---|
| 551 | <row> |
---|
| 552 | <entry><code>L lk(m);</code></entry> |
---|
| 553 | <entry>Constructs an object <code>lk</code>, and associates mutex |
---|
| 554 | object <code>m</code> with it, then calls |
---|
| 555 | <code>try_lock()</code></entry> |
---|
| 556 | </row> |
---|
| 557 | <row> |
---|
| 558 | <entry><code>L lk(m,b);</code></entry> |
---|
| 559 | <entry>Constructs an object <code>lk</code>, and associates mutex |
---|
| 560 | object <code>m</code> with it, then if <code>b</code>, calls |
---|
| 561 | <code>lock()</code></entry> |
---|
| 562 | </row> |
---|
| 563 | </tbody> |
---|
| 564 | </tgroup> |
---|
| 565 | </table> |
---|
| 566 | </section> |
---|
| 567 | |
---|
| 568 | <section id="threads.concepts.TimedLock"> |
---|
| 569 | <title>TimedLock Concept</title> |
---|
| 570 | |
---|
| 571 | <para>A TimedLock is a refinement of <link |
---|
| 572 | linkend="threads.concepts.TryLock">TryLock</link>. |
---|
| 573 | For a TimedLock type <code>L</code> |
---|
| 574 | and an object <code>lk</code> of that type, |
---|
| 575 | and an object <code>t</code> of type <classname>boost::xtime</classname>, |
---|
| 576 | the following expressions must be well-formed |
---|
| 577 | and have the indicated effects.</para> |
---|
| 578 | |
---|
| 579 | <table> |
---|
| 580 | <title>TimedLock Expressions</title> |
---|
| 581 | <tgroup cols="2"> |
---|
| 582 | <thead> |
---|
| 583 | <row> |
---|
| 584 | <entry>Expression</entry> |
---|
| 585 | <entry>Effects</entry> |
---|
| 586 | </row> |
---|
| 587 | </thead> |
---|
| 588 | |
---|
| 589 | <tbody> |
---|
| 590 | <row> |
---|
| 591 | <entry><code>lk.timed_lock(t)</code></entry> |
---|
| 592 | <entry> |
---|
| 593 | <para>Throws <classname>boost::lock_error</classname> |
---|
| 594 | if locked().</para> |
---|
| 595 | |
---|
| 596 | <para>Makes a blocking attempt |
---|
| 597 | to lock the associated mutex object, and returns <code>true</code> |
---|
| 598 | if successful within the specified time <code>t</code>, otherwise |
---|
| 599 | <code>false</code>. If the associated mutex object is already |
---|
| 600 | locked by the same thread the behavior is dependent on the <link |
---|
| 601 | linkend="threads.concepts.locking-strategies">locking |
---|
| 602 | strategy</link> of the associated mutex object.</para> |
---|
| 603 | </entry> |
---|
| 604 | </row> |
---|
| 605 | </tbody> |
---|
| 606 | </tgroup> |
---|
| 607 | </table> |
---|
| 608 | </section> |
---|
| 609 | |
---|
| 610 | <section id="threads.concepts.ScopedTimedLock"> |
---|
| 611 | <title>ScopedTimedLock Concept</title> |
---|
| 612 | |
---|
| 613 | <para>A ScopedTimedLock is a refinement of <link |
---|
| 614 | linkend="threads.concepts.TimedLock">TimedLock</link>. |
---|
| 615 | For a ScopedTimedLock type <code>L</code> |
---|
| 616 | and an object <code>lk</code> of that type, |
---|
| 617 | and an object <code>m</code> of a type meeting the |
---|
| 618 | <link linkend="threads.concepts.TimedMutex">TimedMutex</link> requirements, |
---|
| 619 | and an object <code>b</code> of type <code>bool</code>, |
---|
| 620 | and an object <code>t</code> of type <classname>boost::xtime</classname>, |
---|
| 621 | the following expressions must be well-formed |
---|
| 622 | and have the indicated effects.</para> |
---|
| 623 | |
---|
| 624 | <table> |
---|
| 625 | <title>ScopedTimedLock Expressions</title> |
---|
| 626 | <tgroup cols="2"> |
---|
| 627 | <thead> |
---|
| 628 | <row> |
---|
| 629 | <entry>Expression</entry> |
---|
| 630 | <entry>Effects</entry> |
---|
| 631 | </row> |
---|
| 632 | </thead> |
---|
| 633 | |
---|
| 634 | <tbody> |
---|
| 635 | <row> |
---|
| 636 | <entry><code>L lk(m,t);</code></entry> |
---|
| 637 | <entry>Constructs an object <code>lk</code>, and associates mutex |
---|
| 638 | object <code>m</code> with it, then calls |
---|
| 639 | <code>timed_lock(t)</code></entry> |
---|
| 640 | </row> |
---|
| 641 | <row> |
---|
| 642 | <entry><code>L lk(m,b);</code></entry> |
---|
| 643 | <entry>Constructs an object <code>lk</code>, and associates mutex |
---|
| 644 | object <code>m</code> with it, then if <code>b</code>, calls |
---|
| 645 | <code>lock()</code></entry> |
---|
| 646 | </row> |
---|
| 647 | </tbody> |
---|
| 648 | </tgroup> |
---|
| 649 | </table> |
---|
| 650 | </section> |
---|
| 651 | </section> |
---|
| 652 | |
---|
| 653 | <section id="threads.concepts.lock-models"> |
---|
| 654 | <title>Lock Models</title> |
---|
| 655 | |
---|
| 656 | <para>&Boost.Threads; currently supplies twelve models of |
---|
| 657 | <link linkend="threads.concepts.Lock">Lock</link> |
---|
| 658 | and its refinements.</para> |
---|
| 659 | |
---|
| 660 | <table> |
---|
| 661 | <title>Lock Models</title> |
---|
| 662 | |
---|
| 663 | <tgroup cols="3"> |
---|
| 664 | <thead> |
---|
| 665 | <row> |
---|
| 666 | <entry>Concept</entry> |
---|
| 667 | <entry>Refines</entry> |
---|
| 668 | <entry>Models</entry> |
---|
| 669 | </row> |
---|
| 670 | </thead> |
---|
| 671 | |
---|
| 672 | <tbody> |
---|
| 673 | <row> |
---|
| 674 | <entry><link linkend="threads.concepts.Lock">Lock</link></entry> |
---|
| 675 | <entry></entry> |
---|
| 676 | <entry></entry> |
---|
| 677 | </row> |
---|
| 678 | <row> |
---|
| 679 | <entry><link linkend="threads.concepts.ScopedLock">ScopedLock</link></entry> |
---|
| 680 | <entry><link linkend="threads.concepts.Lock">Lock</link></entry> |
---|
| 681 | <entry> |
---|
| 682 | <para><classname>boost::mutex::scoped_lock</classname></para> |
---|
| 683 | <para><classname>boost::recursive_mutex::scoped_lock</classname></para> |
---|
| 684 | |
---|
| 685 | <para><classname>boost::try_mutex::scoped_lock</classname></para> |
---|
| 686 | <para><classname>boost::recursive_try_mutex::scoped_lock</classname></para> |
---|
| 687 | |
---|
| 688 | <para><classname>boost::timed_mutex::scoped_lock</classname></para> |
---|
| 689 | <para><classname>boost::recursive_timed_mutex::scoped_lock</classname></para> |
---|
| 690 | </entry> |
---|
| 691 | </row> |
---|
| 692 | <row> |
---|
| 693 | <entry><link linkend="threads.concepts.TryLock">TryLock</link></entry> |
---|
| 694 | <entry><link linkend="threads.concepts.Lock">Lock</link></entry> |
---|
| 695 | <entry></entry> |
---|
| 696 | </row> |
---|
| 697 | <row> |
---|
| 698 | <entry><link linkend="threads.concepts.ScopedTryLock">ScopedTryLock</link></entry> |
---|
| 699 | <entry><link linkend="threads.concepts.TryLock">TryLock</link></entry> |
---|
| 700 | <entry> |
---|
| 701 | <para><classname>boost::try_mutex::scoped_try_lock</classname></para> |
---|
| 702 | <para><classname>boost::recursive_try_mutex::scoped_try_lock</classname></para> |
---|
| 703 | |
---|
| 704 | <para><classname>boost::timed_mutex::scoped_try_lock</classname></para> |
---|
| 705 | <para><classname>boost::recursive_timed_mutex::scoped_try_lock</classname></para> |
---|
| 706 | </entry> |
---|
| 707 | </row> |
---|
| 708 | <row> |
---|
| 709 | <entry><link linkend="threads.concepts.TimedLock">TimedLock</link></entry> |
---|
| 710 | <entry><link linkend="threads.concepts.TryLock">TryLock</link></entry> |
---|
| 711 | <entry></entry> |
---|
| 712 | </row> |
---|
| 713 | <row> |
---|
| 714 | <entry><link linkend="threads.concepts.ScopedTimedLock">ScopedTimedLock</link></entry> |
---|
| 715 | <entry><link linkend="threads.concepts.TimedLock">TimedLock</link></entry> |
---|
| 716 | <entry> |
---|
| 717 | <para><classname>boost::timed_mutex::scoped_timed_lock</classname></para> |
---|
| 718 | <para><classname>boost::recursive_timed_mutex::scoped_timed_lock</classname></para> |
---|
| 719 | </entry> |
---|
| 720 | </row> |
---|
| 721 | </tbody> |
---|
| 722 | </tgroup> |
---|
| 723 | </table> |
---|
| 724 | </section> |
---|
| 725 | </section> |
---|
| 726 | |
---|
| 727 | </section> |
---|