Does CPython >= 3.10, <=3.12 support a thread-safe increment?
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
Documentation
There is no information about it in docs. But the code demonstrates that increment works correctly in multithreading context.
import concurrent.futures
def inc():
global count
for _ in range(1000):
count += 1
for threads_count in range(1, 101):
for _ in range(3):
count = 0
with concurrent.futures.ThreadPoolExecutor(max_workers=threads_count) as exe:
for _ in range(10000):
exe.submit(inc)
print(f"{threads_count=}, {count=}")
import dis
dis.dis(inc)
output
threads=1, count=10000000
threads=1, count=10000000
threads=1, count=10000000
threads=2, count=10000000
threads=2, count=10000000
threads=2, count=10000000
threads=3, count=10000000
threads=3, count=10000000
threads=3, count=10000000
threads=4, count=10000000
threads=4, count=10000000
threads=4, count=10000000
threads=5, count=10000000
threads=5, count=10000000
threads=5, count=10000000
threads=6, count=10000000
threads=6, count=10000000
threads=6, count=10000000
threads=7, count=10000000
threads=7, count=10000000
threads=7, count=10000000
threads=8, count=10000000
threads=8, count=10000000
threads=8, count=10000000
threads=9, count=10000000
threads=9, count=10000000
threads=9, count=10000000
threads=10, count=10000000
threads=10, count=10000000
threads=10, count=10000000
threads=11, count=10000000
threads=11, count=10000000
threads=11, count=10000000
threads=12, count=10000000
threads=12, count=10000000
threads=12, count=10000000
threads=13, count=10000000
threads=13, count=10000000
threads=13, count=10000000
threads=14, count=10000000
threads=14, count=10000000
threads=14, count=10000000
threads=15, count=10000000
threads=15, count=10000000
threads=15, count=10000000
threads=16, count=10000000
threads=16, count=10000000
threads=16, count=10000000
threads=17, count=10000000
threads=17, count=10000000
threads=17, count=10000000
threads=18, count=10000000
threads=18, count=10000000
threads=18, count=10000000
threads=19, count=10000000
threads=19, count=10000000
threads=19, count=10000000
threads=20, count=10000000
threads=20, count=10000000
threads=20, count=10000000
threads=21, count=10000000
threads=21, count=10000000
threads=21, count=10000000
threads=22, count=10000000
threads=22, count=10000000
threads=22, count=10000000
threads=23, count=10000000
threads=23, count=10000000
threads=23, count=10000000
threads=24, count=10000000
threads=24, count=10000000
threads=24, count=10000000
threads=25, count=10000000
threads=25, count=10000000
threads=25, count=10000000
threads=26, count=10000000
threads=26, count=10000000
threads=26, count=10000000
threads=27, count=10000000
threads=27, count=10000000
threads=27, count=10000000
threads=28, count=10000000
threads=28, count=10000000
threads=28, count=10000000
threads=29, count=10000000
threads=29, count=10000000
threads=29, count=10000000
threads=30, count=10000000
threads=30, count=10000000
threads=30, count=10000000
threads=31, count=10000000
threads=31, count=10000000
threads=31, count=10000000
threads=32, count=10000000
threads=32, count=10000000
threads=32, count=10000000
threads=33, count=10000000
threads=33, count=10000000
threads=33, count=10000000
threads=34, count=10000000
threads=34, count=10000000
threads=34, count=10000000
threads=35, count=10000000
threads=35, count=10000000
threads=35, count=10000000
threads=36, count=10000000
threads=36, count=10000000
threads=36, count=10000000
threads=37, count=10000000
threads=37, count=10000000
threads=37, count=10000000
threads=38, count=10000000
threads=38, count=10000000
threads=38, count=10000000
threads=39, count=10000000
threads=39, count=10000000
threads=39, count=10000000
threads=40, count=10000000
threads=40, count=10000000
threads=40, count=10000000
threads=41, count=10000000
threads=41, count=10000000
threads=41, count=10000000
threads=42, count=10000000
threads=42, count=10000000
threads=42, count=10000000
threads=43, count=10000000
threads=43, count=10000000
threads=43, count=10000000
threads=44, count=10000000
threads=44, count=10000000
threads=44, count=10000000
threads=45, count=10000000
threads=45, count=10000000
threads=45, count=10000000
threads=46, count=10000000
threads=46, count=10000000
threads=46, count=10000000
threads=47, count=10000000
threads=47, count=10000000
threads=47, count=10000000
threads=48, count=10000000
threads=48, count=10000000
threads=48, count=10000000
threads=49, count=10000000
threads=49, count=10000000
threads=49, count=10000000
threads=50, count=10000000
threads=50, count=10000000
threads=50, count=10000000
threads=51, count=10000000
threads=51, count=10000000
threads=51, count=10000000
threads=52, count=10000000
threads=52, count=10000000
threads=52, count=10000000
threads=53, count=10000000
threads=53, count=10000000
threads=53, count=10000000
threads=54, count=10000000
threads=54, count=10000000
threads=54, count=10000000
threads=55, count=10000000
threads=55, count=10000000
threads=55, count=10000000
threads=56, count=10000000
threads=56, count=10000000
threads=56, count=10000000
threads=57, count=10000000
threads=57, count=10000000
threads=57, count=10000000
threads=58, count=10000000
threads=58, count=10000000
threads=58, count=10000000
threads=59, count=10000000
threads=59, count=10000000
threads=59, count=10000000
threads=60, count=10000000
threads=60, count=10000000
threads=60, count=10000000
threads=61, count=10000000
threads=61, count=10000000
threads=61, count=10000000
threads=62, count=10000000
threads=62, count=10000000
threads=62, count=10000000
threads=63, count=10000000
threads=63, count=10000000
threads=63, count=10000000
threads=64, count=10000000
threads=64, count=10000000
threads=64, count=10000000
threads=65, count=10000000
threads=65, count=10000000
threads=65, count=10000000
threads=66, count=10000000
threads=66, count=10000000
threads=66, count=10000000
threads=67, count=10000000
threads=67, count=10000000
threads=67, count=10000000
threads=68, count=10000000
threads=68, count=10000000
threads=68, count=10000000
threads=69, count=10000000
threads=69, count=10000000
threads=69, count=10000000
threads=70, count=10000000
threads=70, count=10000000
threads=70, count=10000000
threads=71, count=10000000
threads=71, count=10000000
threads=71, count=10000000
threads=72, count=10000000
threads=72, count=10000000
threads=72, count=10000000
threads=73, count=10000000
threads=73, count=10000000
threads=73, count=10000000
threads=74, count=10000000
threads=74, count=10000000
threads=74, count=10000000
threads=75, count=10000000
threads=75, count=10000000
threads=75, count=10000000
threads=76, count=10000000
threads=76, count=10000000
threads=76, count=10000000
threads=77, count=10000000
threads=77, count=10000000
threads=77, count=10000000
threads=78, count=10000000
threads=78, count=10000000
threads=78, count=10000000
threads=79, count=10000000
threads=79, count=10000000
threads=79, count=10000000
threads=80, count=10000000
threads=80, count=10000000
threads=80, count=10000000
threads=81, count=10000000
threads=81, count=10000000
threads=81, count=10000000
threads=82, count=10000000
threads=82, count=10000000
threads=82, count=10000000
threads=83, count=10000000
threads=83, count=10000000
threads=83, count=10000000
threads=84, count=10000000
threads=84, count=10000000
threads=84, count=10000000
threads=85, count=10000000
threads=85, count=10000000
threads=85, count=10000000
threads=86, count=10000000
threads=86, count=10000000
threads=86, count=10000000
threads=87, count=10000000
threads=87, count=10000000
threads=87, count=10000000
threads=88, count=10000000
threads=88, count=10000000
threads=88, count=10000000
threads=89, count=10000000
threads=89, count=10000000
threads=89, count=10000000
threads=90, count=10000000
threads=90, count=10000000
threads=90, count=10000000
threads=91, count=10000000
threads=91, count=10000000
threads=91, count=10000000
threads=92, count=10000000
threads=92, count=10000000
threads=92, count=10000000
threads=93, count=10000000
threads=93, count=10000000
threads=93, count=10000000
threads=94, count=10000000
threads=94, count=10000000
threads=94, count=10000000
threads=95, count=10000000
threads=95, count=10000000
threads=95, count=10000000
threads=96, count=10000000
threads=96, count=10000000
threads=96, count=10000000
threads=97, count=10000000
threads=97, count=10000000
threads=97, count=10000000
threads=98, count=10000000
threads=98, count=10000000
threads=98, count=10000000
threads=99, count=10000000
threads=99, count=10000000
threads=99, count=10000000
threads=100, count=10000000
threads=100, count=10000000
threads=100, count=10000000
11 0 LOAD_GLOBAL 0 (range)
2 LOAD_CONST 1 (1000)
4 CALL_FUNCTION 1
6 GET_ITER
>> 8 FOR_ITER 6 (to 22)
10 STORE_FAST 0 (_)12 12 LOAD_GLOBAL 1 (count)
14 LOAD_CONST 2 (1)
16 INPLACE_ADD
18 STORE_GLOBAL 1 (count)
20 JUMP_ABSOLUTE 4 (to 8)11 >> 22 LOAD_CONST 0 (None)
24 RETURN_VALUE
Looks like '+=' isn't an atomic op. But stiil I have a correct result.
Can we just use it as a guarantee or it is just an accent coincidence?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reported ThreadPoolExecutor example, the inc function, and its disassembly. Review the existing Python threading and language-reference documentation to determine what guarantee, if any, applies across CPython 3.10–3.12. Done means the version-specific behavior and whether += may be relied upon are clearly documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100