ErrorStateMatcher проверяет статус родительской формы,
return !!((control && control.touched && control.parent && control.parent.invalid) || (form.submitted));
Убедитесь, что родительская форма действительна или в противном случае она отправлена.
Чтобы устранить ошибки после ввода действительных данных, измените функцию ErrorStateMatcher
return !!((control && control.touched && control.invalid) || (form.submitted));
Да, это будет работать так, как вы описали:
Но я также знайте, что операция del x не является атомарной, если x реализует метод del . Так что, если у моего элемента есть метод del и происходит какое-то неприятное планирование, все может сломаться.
Я не вижу здесь "дель". Если del происходит в consumer_item, тогда del может возникнуть в производственном потоке. Я не думаю, что это будет "проблемой".
Не беспокойтесь об этом. В конечном итоге вы будете использовать ЦП в бессмысленных циклах опроса, и это не быстрее, чем использование очереди с блокировками, поскольку Python уже имеет глобальную блокировку.
Обман укусит вас. Просто используйте Queue для связи между потоками.
Это не на самом деле потокобезопасность, потому что производитель может перезаписать QUEUE_ITEM
до того, как потребитель потребит его, а потребитель может использовать QUEUE_ITEM
дважды , Как вы упомянули, вы согласны с этим, но большинство людей нет.
Кто-то с большим знанием внутреннего устройства cpython должен ответить вам на более теоретические вопросы.
Я думаю, что возможно, что поток прерывается во время производства / потребления, особенно если это большие объекты. Изменить: это просто дикая догадка. Я не эксперт.
Также потоки могут производить / потреблять любое количество элементов до того, как другой начнет работать.
Вы можете использовать список в качестве очереди, пока вы придерживаетесь добавления / извлечения, поскольку оба они атомарны.
QUEUE = []
# this is executed in one threading.Thread object
def producer():
global QUEUE
while True:
i = produce_item()
QUEUE.append(i)
# this is executed in another threading.Thread object
def consumer():
global QUEUE
while True:
try:
i = QUEUE.pop(0)
except IndexError:
# queue is empty
continue
consume_item(i)
В области действия класса, как показано ниже, вы даже можете очистить очередь.
class Atomic(object):
def __init__(self):
self.queue = []
# this is executed in one threading.Thread object
def producer(self):
while True:
i = produce_item()
self.queue.append(i)
# this is executed in another threading.Thread object
def consumer(self):
while True:
try:
i = self.queue.pop(0)
except IndexError:
# queue is empty
continue
consume_item(i)
# There's the possibility producer is still working on it's current item.
def clear_queue(self):
self.queue = []
Вам нужно будет выяснить, какие операции со списком являются атомарными, посмотрев на сгенерированный байт-код.
__ del __
может быть проблемой, как Вы сказали. Этого можно было бы избежать, если бы только существовал способ запретить сборщику мусора вызывать метод __ del __
для старого объекта до того, как мы завершим назначение нового для QUEUE_ITEM
. Нам понадобится что-то вроде:
increase the reference counter on the old object
assign a new one to `QUEUE_ITEM`
decrease the reference counter on the old object
Боюсь, но не знаю, возможно ли это.