Skip to content

Commit 12e6207

Browse files
committed
Add AtomicCounter class to threading module
- Implemented AtomicCounter class for thread-safe increment and decrement operations. - Ensured thread safety using a Lock.
1 parent 2ed5ee9 commit 12e6207

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

Lib/test/test_threading.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,6 +2339,30 @@ def run_last():
23392339
self.assertIn("RuntimeError: can't register atexit after shutdown",
23402340
err.decode())
23412341

2342+
class TestAtomicCounter(unittest.TestCase):
2343+
def setUp(self):
2344+
self.counter = threading.AtomicCounter()
2345+
2346+
def test_initial_value(self):
2347+
self.assertEqual(self.counter.get(), 0)
2348+
2349+
def test_increment(self):
2350+
self.counter.inc()
2351+
self.assertEqual(self.counter.get(), 1)
2352+
self.counter.inc(5)
2353+
self.assertEqual(self.counter.get(), 6)
2354+
2355+
def test_decrement(self):
2356+
self.counter.dec()
2357+
self.assertEqual(self.counter.get(), -1)
2358+
self.counter.dec(5)
2359+
self.assertEqual(self.counter.get(), -6)
2360+
2361+
def test_increment_and_decrement(self):
2362+
self.counter.inc(10)
2363+
self.counter.dec(3)
2364+
self.assertEqual(self.counter.get(), 7)
2365+
23422366

23432367
if __name__ == "__main__":
23442368
unittest.main()

Lib/threading.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
'Barrier', 'BrokenBarrierError', 'Timer', 'ThreadError',
3030
'setprofile', 'settrace', 'local', 'stack_size',
3131
'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile',
32-
'setprofile_all_threads','settrace_all_threads']
32+
'setprofile_all_threads','settrace_all_threads', 'AtomicCounter']
3333

3434
# Rename some stuff so "from threading import *" is safe
3535
_start_joinable_thread = _thread.start_joinable_thread
@@ -857,6 +857,31 @@ def _newname(name_template):
857857
_dangling = WeakSet()
858858

859859

860+
class AtomicCounter:
861+
"""Threadsafe counter.
862+
863+
Returns the value after inc/dec operations.
864+
"""
865+
866+
def __init__(self, initial=0):
867+
self._value = initial
868+
self._lock = Lock()
869+
870+
def inc(self, n=1):
871+
with self._lock:
872+
self._value += n
873+
return self._value
874+
875+
def dec(self, n=1):
876+
with self._lock:
877+
self._value -= n
878+
return self._value
879+
880+
def get(self):
881+
with self._lock:
882+
return self._value
883+
884+
860885
# Main class for threads
861886

862887
class Thread:

0 commit comments

Comments
 (0)