Oto coś takiego można obserwować:
>>> from threading import Thread
>>> from time import sleep
>>> liszt = ['first item', 'second item', 'third item', 'fourth item',
... 'plentee more items', "but I'm lazy"]
>>> def thread_one():
... for i in liszt:
... print 'Thread one found "%s"' % i
... sleep(1)
...
>>> def thread_two():
... sleep(0.5)
... print 'Thread two deleting first item.'
... del liszt[0]
... sleep(1)
... print 'Thread two deleting fourth item.'
... del liszt[3]
...
>>> Thread(target=thread_one).start(); Thread(target=thread_two).start()
Thread one found "first item"
Thread two deleting first item.
Thread one found "third item"
Thread two deleting fourth item.
Thread one found "fourth item"
Thread one found "but I'm lazy"
Z tego widać, że modyfikowanie listy w jednym wątku wpływa iteratora w innym wątku; usunięcie pierwszego elementu spowodowało, że iterator pominął element, usunięcie przyszłego elementu oznacza, że nie będzie widoczne w iteratorze, ponieważ zniknęło.
Oto model niektórych z tego, jak to działa; Nie dostarczam tego wyraźnie, ale możesz to zrobić z obserwacji.
State: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Iterator position:^
Przejdź do następnego artykułu.
State: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Iterator position: ^
Usuń pierwszy element.
State: [2, 3, 4, 5, 6, 7, 8, 9, 10]
Iterator position: ^
Przejdź do następnego artykułu.
State: [2, 3, 4, 5, 6, 7, 8, 9, 10]
Iterator position: ^
Usuń piąty element.
State: [2, 3, 4, 5, 7, 8, 9, 10]
Iterator position: ^
Et cetera. W kwestii wątkowania nie ma znaczenia, czy robisz to w jednym wątku czy w wielu wątkach. Oczywiście, możesz mieć warunek wyścigu, czy przedmiot został usunięty, czy nie, ale nadal działa w ten sam sposób.
Jeśli nie znasz wewnętrznych wersji iteracji, skontaktuj się z iter
. for x in y
iteruje ponad iter(y)
, w rzeczywistości. Tak więc możesz grać z obiektem listiteratora iter(liszt)
, jeśli chcesz, używając next()
na nim, podczas gdy grasz z listą, którą iteruje. Bardziej wygodny niż pętla for w interaktywnej konsoli Python.
Czy próbowałeś * go? –
@ChrisMorgan Problemy z kondycją Race są bardzo trudne do znalezienia. Dlatego też próba ta może wykazać tylko oczywisty błąd i nie może pokazać inaczej. Co gorsza, GIL programu cpython będzie konsekwentnie ukrywać błędy. – phihag
@ChrisMorgan Mam taki pomysł w moim obecnym projekcie, ale nie powoduje to błędu krytycznego i nie mogę znaleźć prostego, ale przekonującego przykładu, aby ujawnić prawdę. – onemach