Python - Threading e um While True loop
-
03-07-2019 - |
Pergunta
Eu tenho um segmento que anexa linhas a self.output e um loop que vai até self.done é True (ou o tempo de execução máximo é atingido).
Existe uma maneira mais eficiente de fazer isso além de usar um tempo loop que verifica constantemente para ver se ele é feito. O loop while faz com que a CPU para picos a 100% enquanto ele está funcionando ..
time.clock()
while True:
if len(self.output):
yield self.output.pop(0)
elif self.done or 15 < time.clock():
if 15 < time.clock():
yield "Maximum Execution Time Exceeded %s seconds" % time.clock()
break
Solução
São os seus tópicos anexando a self.output aqui, com sua principal tarefa consumi-los? Se assim for, este é um trabalho feito sob medida para Queue.Queue . O código deve se tornar algo como:
import Queue
# Initialise queue as:
queue = Queue.Queue()
Finished = object() # Unique marker the producer will put in the queue when finished
# Consumer:
try:
while True:
next_item = self.queue.get(timeout=15)
if next_item is Finished: break
yield next_item
except Queue.Empty:
print "Timeout exceeded"
Seus segmentos produtores adicionar itens à fila com queue.put(item)
[Edit] O código original tem uma questão racial ao verificar self.done (por exemplo, vários itens podem ser acrescentados à fila antes da bandeira está definido, fazendo com que o código para salvar a primeiro). Atualizado com uma sugestão de ??O????? -. O segmento produtor deve, em vez de acrescentar um símbolo especial (Terminado) para a fila para indicar que está completa ??p>
Nota: Se você tiver vários segmentos produtores, você vai precisar de uma abordagem mais geral para detectar quando eles estão todos terminado. Você poderia fazer isso com a mesma estratégia -. Cada thread um marcador concluído eo termina consumidor quando vê NUM_THREADS marcadores
Outras dicas
Use um semáforo; tem a liberação fio trabalhando-lo quando ele está acabado, e bloquear seu segmento acrescentando até que o trabalhador está acabado com o semáforo.
ie. no trabalho, fazer algo como self.done = threading.Semaphore()
no início do trabalho, e self.done.release()
quando terminar. No código que anotou acima, em vez do circuito ocupado, basta fazer self.done.acquire()
; quando o segmento de trabalho é concluído, o controle retornará.
Edit: Eu tenho medo que eu não resolver o seu valor de tempo limite necessário, embora; este href="http://bugs.python.org/issue850728" questão descreve a necessidade de um tempo de espera do semáforo na biblioteca padrão.
Use time.sleep (segundos) para criar uma pausa breve depois de cada iteração do loop while a abandonar a cpu. Você terá que definir o tempo você dorme durante cada iteração com base em quão importante é que você pegar o trabalho rapidamente depois que é completa.
Exemplo:
time.clock()
while True:
if len(self.output):
yield self.output.pop(0)
elif self.done or 15 < time.clock():
if 15 < time.clock():
yield "Maximum Execution Time Exceeded %s seconds" % time.clock()
break
time.sleep(0.01) # sleep for 10 milliseconds
módulo de uso mutex ou evento / semáforo
Você tem que usar uma sincronização primitiva aqui. Olhe aqui: http://docs.python.org/library/threading.html .
Os objetos de evento parece muito simples e deve resolver o seu problema. Você também pode usar um objeto condição ou um semáforo.
Eu não postar um exemplo, porque eu nunca usei objetos Event, e as alternativas são provavelmente menos simples.
Editar: Estou realmente não tem certeza eu entendi o seu problema. Se um thread pode esperar até que alguma condição é statisfied, use a sincronização. Caso contrário, a solução sleep()
que alguém postou vontade de tomar muito tempo de CPU.