|
1 | | -# My Python Package |
| 1 | +# concurrent_collections |
| 2 | + |
| 3 | +Thread-safe Python collections: `ConcurrentBag`, `ConcurrentDictionary`, and `ConcurrentQueue`. |
2 | 4 |
|
3 | 5 | ## Overview |
4 | 6 |
|
5 | | -My Python Package is a Python library designed to provide essential functionalities for [briefly describe the purpose of your package]. It aims to [describe the goals or features of the package]. |
| 7 | +Python's built-in `list`, `dict`, and `deque` are thread safe for some operations, but not all. |
| 8 | + |
| 9 | +`concurrent_collections` provides thread-safe alternatives by using locks internally to ensure safe concurrent access and mutation from multiple threads. |
| 10 | + |
| 11 | +## Why use these collections? |
| 12 | + |
| 13 | +Python's built-in collections are **not fully thread-safe** for all operations. While some simple operations (like `list.append()` or `dict[key] = value`) are thread-safe due to the Global Interpreter Lock (GIL), **compound operations and iteration with mutation are not**. This can lead to subtle bugs, race conditions, or even crashes in multi-threaded programs. |
| 14 | + |
| 15 | +See the [Python FAQ: "What kinds of global value mutation are thread-safe?"](https://docs.python.org/3/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe) for details. The FAQ explains that only a handful of simple operations are guaranteed to be atomic and thread-safe. For anything more complex, you must use your own locking or a thread-safe collection. |
| 16 | + |
| 17 | +`concurrent_collections` provides drop-in replacements that handle locking for you, making concurrent programming safer and easier. |
6 | 18 |
|
7 | 19 | ## Installation |
8 | 20 |
|
9 | | -You can install the package using pip: |
| 21 | +Pip: |
10 | 22 |
|
| 23 | +```bash |
| 24 | +pip install python-nameof |
11 | 25 | ``` |
12 | | -pip install my_python_package |
| 26 | + |
| 27 | +My recommendation is to always use [`uv`](https://docs.astral.sh/uv/) instead of pip – I personally think it's the best package and environment manager for Python. |
| 28 | + |
| 29 | +```bash |
| 30 | +uv add python-nameof |
13 | 31 | ``` |
14 | 32 |
|
15 | | -## Usage |
| 33 | +## Collections |
16 | 34 |
|
17 | | -Here is a simple example of how to use My Python Package: |
| 35 | +### ConcurrentBag |
| 36 | + |
| 37 | +A thread-safe, list-like collection. |
18 | 38 |
|
19 | 39 | ```python |
20 | | -from my_python_package import core |
| 40 | +from concurrent_collections import ConcurrentBag |
21 | 41 |
|
22 | | -# Example usage of core functionality |
23 | | -result = core.some_function() |
24 | | -print(result) |
| 42 | +bag = ConcurrentBag([1, 2, 3]) |
| 43 | +bag.append(4) |
| 44 | +print(list(bag)) # [1, 2, 3, 4] |
25 | 45 | ``` |
26 | 46 |
|
27 | | -## Contributing |
| 47 | +### ConcurrentDictionary |
| 48 | + |
| 49 | +A thread-safe dictionary. For atomic compound updates, use `update_atomic`. |
28 | 50 |
|
29 | | -Contributions are welcome! Please feel free to submit a pull request or open an issue for any suggestions or improvements. |
| 51 | +```python |
| 52 | +from concurrent_collections import ConcurrentDictionary |
| 53 | + |
| 54 | +d = ConcurrentDictionary({'x': 1}) |
| 55 | +d['y'] = 2 # Simple assignment is thread-safe |
| 56 | +# For atomic updates: |
| 57 | +d.update_atomic('x', lambda v: v + 1) |
| 58 | +print(d['x']) # 2 |
| 59 | +``` |
| 60 | + |
| 61 | +### ConcurrentQueue |
| 62 | + |
| 63 | +A thread-safe double-ended queue. |
| 64 | + |
| 65 | +```python |
| 66 | +from concurrent_collections import ConcurrentQueue |
| 67 | + |
| 68 | +q = ConcurrentQueue() |
| 69 | +q.append(1) |
| 70 | +q.appendleft(0) |
| 71 | +print(q.pop()) # 1 |
| 72 | +print(q.popleft()) # 0 |
| 73 | +``` |
30 | 74 |
|
31 | 75 | ## License |
32 | 76 |
|
33 | | -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. |
| 77 | +MIT License |
0 commit comments