Evento de threading Python

Resumo : neste tutorial, você aprenderá como usar o objeto Event de threading do Python para se comunicar entre threads.

Introdução ao objeto de evento de threading Python

Às vezes, você precisa se comunicar entre os threads . Para fazer isso, você pode usar um lock (mutex) e uma variável booleana.

No entanto, Python fornece uma maneira melhor de comunicação entre threads usando a Eventclasse do threadingmódulo.

A Eventclasse oferece uma maneira simples, mas eficaz de coordenar threads: um thread sinaliza um evento enquanto outros threads esperam por ele.

O Eventobjeto envolve um sinalizador booleano que pode ser definido ( True) ou desmarcado ( False). Vários threads podem esperar que um Eventseja definido antes de continuar ou podem redefinir Evento estado desmarcado.

A seguir ilustramos as etapas para usar o Eventobjeto:

Primeiro, importe do Eventmódulo threading:

from threading import EventLinguagem de código:  Python  ( python )

A seguir, crie um novo Eventobjeto:

event = Event()Linguagem de código:  Python  ( python )

Por padrão, o evento não está definido (desmarcado). O is_set()método do objeto de evento retornará False:

if event.is_set():
   # ...Linguagem de código:  Python  ( python )

Em seguida, defina um evento usando o set()método:

event.set()Linguagem de código:  Python  ( python )

Assim que um evento for definido, todos os threads que aguardam o evento serão notificados automaticamente.

Depois disso, desmarque um evento através do clear()método:

event.clear()Linguagem de código:  Python  ( python )

Finalmente, os threads podem esperar que o evento seja definido através do wait()método:

event.wait()Linguagem de código:  Python  ( python )

O wait()método bloqueia a execução de um thread até que o evento seja definido. Em outras palavras, o wait()método bloqueará o thread atual até que outro thread chame o set()método para definir o evento.

Se um evento for definido, a wait()função retornará imediatamente.

Para especificar quanto tempo o thread irá esperar, você pode usar o argumento timeout. Por exemplo:

event.wait(timeout=5) # wait for 5 secondsLinguagem de código:  Python  ( python )

Exemplo de evento de threading Python

O exemplo a seguir mostra um exemplo simples de uso do Eventobjeto para comunicação entre threads:

from threading import Thread, Event
from time import sleep

def task(event: Event, id: int) -> None:
    print(f'Thread {id} started. Waiting for the signal....')
    event.wait()
    print(f'Received signal. The thread {id} was completed.')

def main() -> None:
    event = Event()

    t1 = Thread(target=task, args=(event,1))
    t2 = Thread(target=task, args=(event,2))

    t1.start()
    t2.start()

    print('Blocking the main thread for 3 seconds...')
    sleep(3) 
    event.set()



if __name__ == '__main__':
    main()Linguagem de código:  Python  ( python )

Saída:

Thread 1 started. Waiting for the signal....
Thread 2 started. Waiting for the signal....
Blocking the main thread for 3 seconds...
Received signal. The thread 1 was completed.
Received signal. The thread 2 was completed.Linguagem de código:  Python  ( python )

Como funciona.

Primeiro, defina a task()função que aceita um Eventobjeto e um número inteiro:

def task(event: Event, id: int) -> None:
    print(f'Thread {id} started. Wait for the signal....')
    event.wait()
    print(f'Receive signal. The thread {id} was completed.')Linguagem de código:  Python  ( python )

Dentro da task()função, chamamos o wait()método do objeto de evento para aguardar que o evento seja definido pelo thread principal.

Segundo, crie um Eventobjeto dentro da main()função:

event = Event()Linguagem de código:  Python  ( python )

Terceiro, crie dois threads filhos que executam a task()função com o mesmo objeto de evento e IDs 1 e 2 diferentes:

t1 = Thread(target=task, args=(event,1))
t2 = Thread(target=task, args=(event,2))Linguagem de código:  Python  ( python )

Quarto, inicie ambos os threads chamando o start()método:

t1.start()
t2.start()Linguagem de código:  Python  ( python )

Quinto, chame o sleep()método para bloquear o thread principal por três segundos:

sleep(3)Linguagem de código:  Python  ( python )

Como a task()função chama o wait()método do objeto de evento, ambos t1os t2threads aguardarão a definição do evento antes de continuar.

Finalmente, defina o evento chamando o set()método do thread principal:

event.set()Linguagem de código:  Python  ( python )

Ambos t1os t2threads serão notificados e continuarão em execução até o final.

Observe que você aprenderá como usar o objeto Event para interromper um thread filho do thread principal no próximo tutorial.

Exemplo prático de utilização do evento Threading

O exemplo a seguir ilustra como usar o evento threading para sincronizar entre dois threads:

  • O thread nº 1 baixa um arquivo de texto de URL https://www.ietf.org/rfc/rfc793.txte, uma vez concluído, notifica o segundo thread para contar as palavras do arquivo de texto baixado.
  • O thread nº 2 é iniciado e aguarda o sinal concluído do thread nº 1. Ao receber o sinal, ele começa a contar as palavras do arquivo baixado.

Aqui está o programa completo:

from threading import Thread, Event
from urllib import request


def download_file(url, event):
    # Download the file form URL
    print(f"Downloading file from {url}...")
    filename, _ = request.urlretrieve(url, "rfc793.txt")

    # File download completed, set the event
    event.set()


def process_file(event):
    print("Waiting for the file to be downloaded...")
    event.wait()  # Wait for the event to be set

    # File has been downloaded, start processing it
    print("File download completed. Starting file processing...")

    # Count the number of words in the file
    word_count = 0
    with open("rfc793.txt", "r") as file:
        for line in file:
            words = line.split()
            word_count += len(words)

    # Print the word count
    print(f"Number of words in the file: {word_count}")


def main():
    # Create an Event object
    event = Event()

    # Create and start the file download thread
    download_thread = Thread(target=download_file, 
                             args=("https://www.ietf.org/rfc/rfc793.txt",  event))

    download_thread.start()

    # Create and start the file processing thread
    process_thread = Thread(target=process_file, args=(event,))
    process_thread.start()

    # Wait for both threads to complete
    download_thread.join()
    process_thread.join()

    print("Main thread finished.")

if __name__ == '__main__'    :
    main()
Linguagem de código:  PHP  ( php )

Resumo

  • Use a threading.Eventclasse para comunicação entre threads.
  • Use o set()método para definir o evento e clear()o método para cancelar a configuração do evento.
  • Use o is_set()método para verificar se um evento está definido.
  • Use o wait()método para aguardar a definição do evento.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *