[Python-checkins] bpo-32208: update threading.Semaphore docs and add unit test (#4709)

Andrew Svetlov webhook-mailer at python.org
Thu Dec 7 13:04:31 EST 2017


https://github.com/python/cpython/commit/a0374dd34aa25f0895195d388b5ceff43b121b00
commit: a0374dd34aa25f0895195d388b5ceff43b121b00
branch: master
author: Garrett Berg <googberg at gmail.com>
committer: Andrew Svetlov <andrew.svetlov at gmail.com>
date: 2017-12-07T20:04:26+02:00
summary:

bpo-32208: update threading.Semaphore docs and add unit test (#4709)

* fix issue32208: update threading.Semaphore docs and add unit test to validate correct behavior

* add test for blocking

* Update threading.rst

* semaphore: remove documentation validation tests and move 'return value' test to BaseSemaphore

files:
M Doc/library/threading.rst
M Lib/test/lock_tests.py

diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst
index 95e27cab7c8..b94021b4eb8 100644
--- a/Doc/library/threading.rst
+++ b/Doc/library/threading.rst
@@ -684,8 +684,8 @@ Semaphores also support the :ref:`context management protocol <with-locks>`.
 
 .. class:: Semaphore(value=1)
 
-   This class implements semaphore objects.  A semaphore manages a counter
-   representing the number of :meth:`release` calls minus the number of
+   This class implements semaphore objects.  A semaphore manages an atomic
+   counter representing the number of :meth:`release` calls minus the number of
    :meth:`acquire` calls, plus an initial value.  The :meth:`acquire` method
    blocks if necessary until it can return without making the counter negative.
    If not given, *value* defaults to 1.
@@ -701,19 +701,19 @@ Semaphores also support the :ref:`context management protocol <with-locks>`.
 
       Acquire a semaphore.
 
-      When invoked without arguments: if the internal counter is larger than
-      zero on entry, decrement it by one and return immediately.  If it is zero
-      on entry, block, waiting until some other thread has called
-      :meth:`~Semaphore.release` to make it larger than zero.  This is done
-      with proper interlocking so that if multiple :meth:`acquire` calls are
-      blocked, :meth:`~Semaphore.release` will wake exactly one of them up.
-      The implementation may pick one at random, so the order in which
-      blocked threads are awakened should not be relied on.  Returns
-      true (or blocks indefinitely).
+      When invoked without arguments:
+
+      * If the internal counter is larger than zero on entry, decrement it by
+        one and return true immediately.
+      * If the internal counter is zero on entry, block until awoken by a call to
+        :meth:`~Semaphore.release`.  Once awoken (and the counter is greater
+        than 0), decrement the counter by 1 and return true.  Exactly one
+        thread will be awoken by each call to :meth:`~Semaphore.release`.  The
+        order in which threads are awoken should not be relied on.
 
       When invoked with *blocking* set to false, do not block.  If a call
-      without an argument would block, return false immediately; otherwise,
-      do the same thing as when called without arguments, and return true.
+      without an argument would block, return false immediately; otherwise, do
+      the same thing as when called without arguments, and return true.
 
       When invoked with a *timeout* other than ``None``, it will block for at
       most *timeout* seconds.  If acquire does not complete successfully in
diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py
index a1ea96d42ce..5b1f033c6f8 100644
--- a/Lib/test/lock_tests.py
+++ b/Lib/test/lock_tests.py
@@ -629,13 +629,14 @@ def test_acquire_contended(self):
         sem = self.semtype(7)
         sem.acquire()
         N = 10
+        sem_results = []
         results1 = []
         results2 = []
         phase_num = 0
         def f():
-            sem.acquire()
+            sem_results.append(sem.acquire())
             results1.append(phase_num)
-            sem.acquire()
+            sem_results.append(sem.acquire())
             results2.append(phase_num)
         b = Bunch(f, 10)
         b.wait_for_started()
@@ -659,6 +660,7 @@ def f():
         # Final release, to let the last thread finish
         sem.release()
         b.wait_for_finished()
+        self.assertEqual(sem_results, [True] * (6 + 7 + 6 + 1))
 
     def test_try_acquire(self):
         sem = self.semtype(2)



More information about the Python-checkins mailing list