Skip to main content

A brief description of concurrent-collections

Project description

Python Concurrent (thread-safe) collections

Run all tests

tl;dr

Despite what many people think, Python's built-in list, dict, and deque are NOT thread-safe.
They may be thread safe for some operations, but not all.
This created a lot of confusion in the Python community.
Google style-guide recommends to not rely on atomicity of built-in collections.

concurrent_collections provides thread-safe alternatives by using locks internally to ensure safe concurrent access and mutation from multiple threads.

Inspired from the amazing C#'s concurrent collections.

Why use these collections?

There is a lot of confusion on whether Python collections are thread-safe or not1, 2, 3.

The bottom line is that 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.

See the Python FAQ: "What kinds of global value mutation are thread-safe?" for details. The FAQ explains that only some (if common) operations are guaranteed to be atomic and thread-safe, but for anything more complex, you must use your own locking.
The docs even go as far as to say:

When in doubt, use a mutex!

Which is telling.

Even Google recommends to not rely on atomicity of built-in collections.

This concurrent_collections library provides drop-in replacements that handle locking for you.
Suggestions and feedbacks are welcome.

  1. Are lists thread-safe?

  2. Google style guide advises against relying on Python's assignment atomicity

  3. What kind of "thread safe" are deque's actually?

Installation

Pip:

pip install concurrent_collections

My recommendation is to always use uv instead of pip – I personally think it's the best package and environment manager for Python.

uv add concurrent_collections

Collections

ConcurrentBag

A thread-safe, list-like collection.

from concurrent_collections import ConcurrentBag

bag = ConcurrentBag([1, 2, 3])
bag.append(4)
print(list(bag))  # [1, 2, 3, 4]

ConcurrentDictionary

A thread-safe dictionary. It has a few notable methods:

  • assign_atomic()
  • get_locked()
  • update_atomic()

ConcurrentDictionary's assign_atomic()

Assigns a dictionary value under a key in a thread-safe way. While dict["somekey"] = value is allowed, it's best to use assign_atomic() for clarity of intent. Using normal assignment will work but raise a UserWarning.

ConcurrentDictionary's get_locked()

When working with ConcurrentDictionary, you should use the get_locked method to safely read or update the value for a specific key in a multi-threaded environment. This ensures that only one thread can access or modify the value for a given key at a time, preventing race conditions.

from concurrent_collections import ConcurrentDictionary

d = ConcurrentDictionary({'x': "some value" })

# Safely read and update the value for 'x'
with d.get_locked('x') as value:
    # value is locked for this thread
    d['x'] = "new value"

ConcurrentDictionary's update_atomic()

Performs a thread-safe, in-place update to an existing value under a key.

d = ConcurrentDictionary({'x': 1 })
d.update_atomic("x", lambda v: v + 1) # d now contains 2 under the 'x' key.

ConcurrentQueue

A thread-safe double-ended queue.

from concurrent_collections import ConcurrentQueue

q = ConcurrentQueue()
q.append(1)
q.appendleft(0)
print(q.pop())      # 1
print(q.popleft())  # 0

License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

concurrent_collections-2.0.1.tar.gz (6.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

concurrent_collections-2.0.1-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file concurrent_collections-2.0.1.tar.gz.

File metadata

  • Download URL: concurrent_collections-2.0.1.tar.gz
  • Upload date:
  • Size: 6.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for concurrent_collections-2.0.1.tar.gz
Algorithm Hash digest
SHA256 d19196a2fc241a3341bf73250aafebaba203da6c5a8edcc1e8f02ea943b90e02
MD5 676e422614066f3cd871ee7f3f1c2f8c
BLAKE2b-256 b5208562e55d673d33f3b6c068225f7fc49f49600e0d61a54912506d257c50a8

See more details on using hashes here.

File details

Details for the file concurrent_collections-2.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for concurrent_collections-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2c2b6d20ecbb3c081f22ac6a1b692b6c6335cd31a82310c6f0613f8ca040d28a
MD5 3146e03d2a6f6c26c18c7904284ae9a1
BLAKE2b-256 e4f8c1b0d30c3174acee942ddca17997a0e57c711a685be20f86d0c6a13362a7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page