This repository was archived by the owner on Apr 11, 2026. It is now read-only.
File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -14,7 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
1414
1515---
1616
17- ## [ 1.1.0] - 2025-03-23
17+ ## [ 1.1.0] - 2025-03-26
1818### Classes Added
1919### 1. Dynaphore
2020- A dynamic semaphore class that allows for dynamic tuning of semaphore limits.
Original file line number Diff line number Diff line change 66from src .thread_factory .concurrency .concurrent_stack import ConcurrentStack
77from src .thread_factory .concurrency .concurrent_buffer import ConcurrentBuffer
88
9+
910__all__ = [
1011 "ConcurrentBag" ,
1112 "ConcurrentDict" ,
Original file line number Diff line number Diff line change @@ -147,9 +147,10 @@ class ConcurrentBuffer(Generic[_T]):
147147
148148 **NOTE**: This buffer is not designed for high-contention scenarios.
149149 ConcurrentQueue or ConcurrentStack Outperforms this object in high-contention scenarios.
150+ DO NOT EXCEED 20 THREADS OVERALL (for producer and consumer pattern) WHEN USING THIS OBJECT.
150151
151- 4-6 Shards have given quite good results in most scenarios with under 10 threads, it can
152- outperform the ConcurrentQueue in some scenarios by 2x
152+ Please follow the rule of dividing the number of threads by 2 for the producer and consumer pattern
153+ to obtain shard count. For example, if you have 10 threads, you should use 5 shards.
153154 """
154155
155156 def __init__ (
@@ -183,13 +184,12 @@ def __init__(
183184
184185 def enqueue (self , item : _T ) -> None :
185186 """
186- Adds a new item to the buffer. The item is randomly assigned to one of the internal shards .
187+ Adds a new item to the buffer. The item is to the queue with the least length .
187188
188189 Args:
189190 item (_T): The item to add.
190191 """
191- # Choose a random shard to enqueue the item into. This helps distribute the load.
192- shard_idx = random .randint (0 , self ._num_shards - 1 )
192+ shard_idx = min (range (self ._num_shards ), key = lambda i : self ._length_array [i ])
193193 shard = self ._shards [shard_idx ]
194194 shard .enqueue_item (item )
195195
Original file line number Diff line number Diff line change @@ -56,7 +56,7 @@ def enqueue(self, item: _T) -> None:
5656 with self ._lock :
5757 self ._deque .append (item )
5858
59- def dequeue (self ) -> _T :
59+ def dequeue1 (self ) -> _T :
6060 """
6161 Remove and return an item from the front of the queue.
6262
@@ -72,9 +72,24 @@ def dequeue(self) -> _T:
7272 raise Empty ("dequeue from empty ConcurrentQueue" )
7373 return self ._deque .popleft ()
7474 except Empty :
75- time .sleep (0.10 )
75+ # time.sleep(0.001 )
7676 raise
7777
78+ def dequeue (self ) -> _T :
79+ """
80+ Remove and return an item from the front of the queue.
81+
82+ Raises:
83+ IndexError: If the queue is empty.
84+
85+ Returns:
86+ _T: The item dequeued.
87+ """
88+ with self ._lock :
89+ if not self ._deque :
90+ raise Empty ("dequeue from empty ConcurrentQueue" )
91+ return self ._deque .popleft ()
92+
7893 def peek (self ) -> _T :
7994 """
8095 Return (but do not remove) the item at the front of the queue.
Original file line number Diff line number Diff line change 11import threading
22import cProfile
33import pstats
4-
5-
6- def test ():
7- print ("Test begins" )
8- print ("Lock Acquired" )
9- print ("This is the thread ID " + str (threading .get_ident ()))
10- x = threading .RLock ()
11- x .acquire ()
12- print ("Lock Released" )
13- x .release ()
14- print ("Deadlock" )
15- x .acquire ()
16- x .acquire ()
17- print ("Test ends" )
18-
19- test ()
20-
21- # profiler = cProfile.Profile()
22- # profiler.enable()
23- #
24- # # 🔁 Run your test or logic here
25- # my_buffer.stress_test()
26- #
27- # profiler.disable()
28- #
29- # # 📊 Print top 30 slowest functions by cumulative time
30- # stats = pstats.Stats(profiler).sort_stats("cumtime")
31- # stats.print_stats(30)
32-
33-
34-
35- testing = threading .Thread (target = test )
36- testing2 = threading .Thread (target = test )
37- testing3 = threading .Thread (target = test )
38- testing4 = threading .Thread (target = test )
39-
40-
41- testing .start ()
42- testing2 .start ()
43- testing3 .start ()
44- testing4 .start ()
45-
46-
47-
Original file line number Diff line number Diff line change @@ -550,10 +550,10 @@ def test_threaded_concurrent_buffer_performance(self):
550550 High-performance producer/consumer test using threads and ConcurrentBuffer.
551551 Balanced consumer workload to avoid stalling.
552552 """
553- self .buffer = ConcurrentBuffer (4 )
554- producers = 8
555- consumers = 8
556- self .items_per_producer = 50_000
553+ self .buffer = ConcurrentBuffer (10 )
554+ producers = 10
555+ consumers = 10
556+ self .items_per_producer = 100_000
557557 total_items = producers * self .items_per_producer
558558
559559 try :
@@ -580,7 +580,8 @@ def consumer(target):
580580 _ = self .buffer .dequeue ()
581581 consumed += 1
582582 except Empty :
583- time .sleep (0.001 )
583+ pass
584+ #time.sleep(0.001)
584585
585586 threads = []
586587 for pid in range (producers ):
@@ -664,9 +665,9 @@ def test_threaded_concurrent_queue_performance(self):
664665 """
665666 from thread_factory import ConcurrentQueue
666667 q = ConcurrentQueue ()
667- producers = 8
668- consumers = 8
669- items_per_producer = 50_000
668+ producers = 10
669+ consumers = 10
670+ items_per_producer = 100_000
670671 total_items = producers * items_per_producer
671672
672673 try :
@@ -693,7 +694,8 @@ def consumer(target):
693694 _ = q .dequeue ()
694695 consumed += 1
695696 except Empty :
696- time .sleep (0.001 )
697+ pass
698+ #time.sleep(0.001)
697699
698700 threads = []
699701 for pid in range (producers ):
Original file line number Diff line number Diff line change @@ -520,7 +520,7 @@ def test_threaded_concurrent_queue_performance(self):
520520 q = ConcurrentQueue ()
521521 producers = 10
522522 consumers = 10
523- items_per_producer = 100000
523+ items_per_producer = 100_000
524524 total_items = producers * items_per_producer
525525
526526 try :
@@ -574,7 +574,7 @@ def test_multiprocessing_queue_performance(self):
574574 queue = multiprocessing .Queue ()
575575 producers = 10
576576 consumers = 10
577- items_per_producer = 100000
577+ items_per_producer = 100_000
578578 total_items = producers * items_per_producer
579579
580580 try :
You can’t perform that action at this time.
0 commit comments