@@ -598,14 +598,25 @@ and "recursion level" in addition to the locked/unlocked state used by primitive |
598 | 598 | locks. In the locked state, some thread owns the lock; in the unlocked state, |
599 | 599 | no thread owns it. |
600 | 600 |
|
601 | | -To lock the lock, a thread calls its :meth:`~RLock.acquire` method; this |
602 | | -returns once the thread owns the lock. To unlock the lock, a thread calls |
603 | | -its :meth:`~Lock.release` method. :meth:`~Lock.acquire`/:meth:`~Lock.release` |
604 | | -call pairs may be nested; only the final :meth:`~Lock.release` (the |
605 | | -:meth:`~Lock.release` of the outermost pair) resets the lock to unlocked and |
606 | | -allows another thread blocked in :meth:`~Lock.acquire` to proceed. |
| 601 | +Threads call a lock's :meth:`~RLock.acquire` method to lock it, |
| 602 | +and its :meth:`~Lock.release` method to unlock it. |
607 | 603 |
|
608 | | -Reentrant locks also support the :ref:`context management protocol <with-locks>`. |
| 604 | +.. note:: |
| 605 | + |
| 606 | + Reentrant locks support the :ref:`context management protocol <with-locks>`, |
| 607 | + so it is recommended to use :keyword:`with` instead of manually calling |
| 608 | + :meth:`~RLock.acquire` and :meth:`~RLock.release` |
| 609 | + to handle acquiring and releasing the lock for a block of code. |
| 610 | + |
| 611 | +RLock's :meth:`~RLock.acquire`/:meth:`~RLock.release` call pairs may be nested, |
| 612 | +unlike Lock's :meth:`~Lock.acquire`/:meth:`~Lock.release`. Only the final |
| 613 | +:meth:`~RLock.release` (the :meth:`~Lock.release` of the outermost pair) resets |
| 614 | +the lock to an unlocked state and allows another thread blocked in |
| 615 | +:meth:`~RLock.acquire` to proceed. |
| 616 | + |
| 617 | +:meth:`~RLock.acquire`/:meth:`~RLock.release` must be used in pairs: each acquire |
| 618 | +must have a release in the thread that has acquired the lock. Failing to |
| 619 | +call release as many times the lock has been acquired can lead to deadlock. |
609 | 620 |
|
610 | 621 |
|
611 | 622 | .. class:: RLock() |
@@ -624,25 +635,41 @@ Reentrant locks also support the :ref:`context management protocol <with-locks>` |
624 | 635 |
|
625 | 636 | Acquire a lock, blocking or non-blocking. |
626 | 637 |
|
627 | | - When invoked without arguments: if this thread already owns the lock, increment |
628 | | - the recursion level by one, and return immediately. Otherwise, if another |
629 | | - thread owns the lock, block until the lock is unlocked. Once the lock is |
630 | | - unlocked (not owned by any thread), then grab ownership, set the recursion level |
631 | | - to one, and return. If more than one thread is blocked waiting until the lock |
632 | | - is unlocked, only one at a time will be able to grab ownership of the lock. |
633 | | - There is no return value in this case. |
| 638 | + .. seealso:: |
634 | 639 |
|
635 | | - When invoked with the *blocking* argument set to ``True``, do the same thing as when |
636 | | - called without arguments, and return ``True``. |
| 640 | + :ref:`Using RLock as a context manager <with-locks>` |
| 641 | + Recommended over manual :meth:`!acquire` and :meth:`release` calls |
| 642 | + whenever practical. |
637 | 643 |
|
638 | | - When invoked with the *blocking* argument set to ``False``, do not block. If a call |
639 | | - without an argument would block, return ``False`` immediately; otherwise, do the |
640 | | - same thing as when called without arguments, and return ``True``. |
641 | 644 |
|
642 | | - When invoked with the floating-point *timeout* argument set to a positive |
643 | | - value, block for at most the number of seconds specified by *timeout* |
644 | | - and as long as the lock cannot be acquired. Return ``True`` if the lock has |
645 | | - been acquired, ``False`` if the timeout has elapsed. |
| 645 | + When invoked with the *blocking* argument set to ``True`` (the default): |
| 646 | + |
| 647 | + * If no thread owns the lock, acquire the lock and return immediately. |
| 648 | + |
| 649 | + * If another thread owns the lock, block until we are able to acquire |
| 650 | + lock, or *timeout*, if set to a positive float value. |
| 651 | + |
| 652 | + * If the same thread owns the lock, acquire the lock again, and |
| 653 | + return immediately. This is the difference between :class:`Lock` and |
| 654 | + :class:`!RLock`; :class:`Lock` handles this case the same as the previous, |
| 655 | + blocking until the lock can be acquired. |
| 656 | + |
| 657 | + When invoked with the *blocking* argument set to ``False``: |
| 658 | + |
| 659 | + * If no thread owns the lock, acquire the lock and return immediately. |
| 660 | + |
| 661 | + * If another thread owns the lock, return immediately. |
| 662 | + |
| 663 | + * If the same thread owns the lock, acquire the lock again and return |
| 664 | + immediately. |
| 665 | + |
| 666 | + In all cases, if the thread was able to acquire the lock, return ``True``. |
| 667 | + If the thread was unable to acquire the lock (i.e. if not blocking or |
| 668 | + the timeout was reached) return ``False``. |
| 669 | + |
| 670 | + If called multiple times, failing to call :meth:`~RLock.release` as many times |
| 671 | + may lead to deadlock. Consider using :class:`!RLock` as a context manager rather than |
| 672 | + calling acquire/release directly. |
646 | 673 |
|
647 | 674 | .. versionchanged:: 3.2 |
648 | 675 | The *timeout* parameter is new. |
@@ -658,7 +685,7 @@ Reentrant locks also support the :ref:`context management protocol <with-locks>` |
658 | 685 |
|
659 | 686 | Only call this method when the calling thread owns the lock. A |
660 | 687 | :exc:`RuntimeError` is raised if this method is called when the lock is |
661 | | - unlocked. |
| 688 | + not acquired. |
662 | 689 |
|
663 | 690 | There is no return value. |
664 | 691 |
|
|