python / python/cpython

nogil list `reverse` breaks atomicity

Ouverte
#129,619 3 commentaires 0 réactions 1 personne assignée Voir sur GitHub

@sobolevn y travaille déjà.

Depuis le 4/2/2025.

interpreter-core topic-free-threading type-bug
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

Description

Bug report

Bug description:

Hi,

We're a research group focused on testing concurrent runtimes. Our work-in-progress prototype found a violation of atomicity on the current nogil build when using list reverse with other concurrent operations on the same list. The program below shows the wrong behavior for reverse and __contains__:

import threading
import sys
def t0(b1,s,res):
    b1.wait()
    s.reverse()

def t1(b1,s,res):
    b1.wait()
    res.append(s.__contains__(3))

def Test():
  l =  [1, 2, 3]
  threads=[]
  barrier = threading.Barrier(2)
  res = []
  threads.append(threading.Thread(target= t0, args=(barrier, l,res)))
  threads.append(threading.Thread(target= t1, args=(barrier, l,res)))
  for i in range(0, len(threads)):
      threads[i].start()
  for i in range(0, len(threads)):
      threads[i].join()
  if res[0] != True:
      print("found bug: " + str(res))

print("test begin...")
for i in range(0,50000):
  threads = []
  if i % 1000 == 0:
      print(i)
  for i in range(0,100):
      threads.append(threading.Thread(target= Test))
  for t in threads:
      t.start()
  for t in threads:
      t.join()
print("test Done")

Operation __contains__ should always see element 3 in the list, either the original or reversed. However, it can see a list without element 3 and return False, as shown in the sample output:

test begin...                                                                                                                                                                                                       
0                                                                                                         
found bug: [False]
found bug: [False]
1000

We observed the same behavior with operations count and index executing concurrently with reverse on the same list, I'll add a comment with those tests and sample outputs.

@flypoodles and @overlorde are part of the team, adding them so they get notified about further discussion.

We note that we observed these outputs in several x86_64 machines and one ARM machine.

CPython versions tested on:

3.14, CPython main branch

Operating systems tested on:

Linux

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.