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
Foi útil?

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

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top