У меня недавно был этот случай, когда мне нужно было непрерывно добавлять в список в одном потоке, циклически проходить по элементам и проверять, готов ли элемент, это был AsyncResult в моем случае и удалять его из списка, только если он былготовы.Я не смог найти ни одного примера, который бы четко продемонстрировал мою проблему. Вот пример, демонстрирующий непрерывное добавление в список в одном потоке и постоянное удаление из этого же списка в другом потоке. Дефектная версия легко работает на меньших числах, но сохраняет числа достаточно большими и запускаетнесколько раз, и вы увидите ошибку
FLAWED версия
import threading
import time
# Change this number as you please, bigger numbers will get the error quickly
count = 1000
l = []
def add():
for i in range(count):
l.append(i)
time.sleep(0.0001)
def remove():
for i in range(count):
l.remove(i)
time.sleep(0.0001)
t1 = threading.Thread(target=add)
t2 = threading.Thread(target=remove)
t1.start()
t2.start()
t1.join()
t2.join()
print(l)
Вывод при ОШИБКЕ
Exception in thread Thread-63:
Traceback (most recent call last):
File "/Users/zup/.pyenv/versions/3.6.8/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/Users/zup/.pyenv/versions/3.6.8/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "<ipython-input-30-ecfbac1c776f>", line 13, in remove
l.remove(i)
ValueError: list.remove(x): x not in list
Версия, в которой используются блокировки
import threading
import time
count = 1000
l = []
r = threading.RLock()
def add():
r.acquire()
for i in range(count):
l.append(i)
time.sleep(0.0001)
r.release()
def remove():
r.acquire()
for i in range(count):
l.remove(i)
time.sleep(0.0001)
r.release()
t1 = threading.Thread(target=add)
t2 = threading.Thread(target=remove)
t1.start()
t2.start()
t1.join()
t2.join()
print(l)
Вывод
[] # Empty list
Вывод
Как уже упоминалосьв предыдущих ответах, в то время как процесс добавления или выталкивания элементов из самого списка является поточно-ориентированным, то, что не является поточно-безопасным, это когда вы добавляете в один поток и вставляете в другой