Como parar um thread em Python

Resumo : neste tutorial, você aprenderá como interromper um thread em Python a partir do thread principal usando a classe Event do módulo threading.

Introdução ao objeto Evento

Para interromper um thread, você usa a Eventclasse do módulo threading . A Eventclasse possui um sinalizador booleano thread-safe interno que pode ser definido como Trueou False. Por padrão, o sinalizador interno é False.

Na Eventclasse, o set()método define o sinalizador interno como Trueenquanto o clear()método redefine o sinalizador como False. Além disso, o is_set()método retorna Truese o sinalizador interno estiver definido como True.

Para interromper um thread filho do thread principal, você usa um Event objeto com as seguintes etapas:

  • Primeiro, crie um novo Eventobjeto e passe-o para um thread filho.
  • Segundo, verifique periodicamente se o sinalizador interno do Eventobjeto está definido no thread filho chamando o is_set()método e interrompa o thread filho se o sinalizador interno tiver sido definido.
  • Terceiro, chame o set()método no thread principal em algum momento para interromper o thread filho.

O fluxograma a seguir ilustra as etapas acima:

thread de parada python

Um exemplo simples de interrupção de um thread em Python

O exemplo a seguir mostra como usar um Eventobjeto para interromper um thread filho do thread principal:

from threading import Thread, Event
from time import sleep

def task(event: Event) -> None:
    for i in range(6):
        print(f'Running #{i+1}')
        sleep(1)
        if event.is_set():
            print('The thread was stopped prematurely.')
            break
    else:
        print('The thread was stopped maturely.')

def main() -> None:

    event = Event()
    thread = Thread(target=task, args=(event,))
    
    # start the thread
    thread.start()

    # suspend  the thread after 3 seconds
    sleep(3)

    # stop the child thread
    event.set()    
   

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

A função tarefa()

A task()função usa um Eventobjeto e retorna None. Ele será executado em um thread filho:

def task(event: Event) -> None:
    for i in range(6):
        print(f'Running #{i+1}')
        sleep(1)
        if event.is_set():
            print('The thread was stopped prematurely.')
            break
    else:
        print('The thread was stopped maturely.')Linguagem de código:  Python  ( python )

A task()função itera sobre os números de 1 a 5. Em cada iteração, usamos a sleep()função para atrasar a execução e sair do loop se o sinalizador interno do objeto de evento estiver definido.

A função main()

Primeiro, crie um novo Eventobjeto:

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

A seguir, crie um novo thread que execute a task()função com um argumento como Eventobjeto:

thread = Thread(target=task, args=(event,))Linguagem de código:  Python  ( python )

Então, comece a executar o thread filho:

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

Depois disso, suspenda o thread principal por três segundos:

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

Finalmente, defina o sinalizador interno do objeto Event como True chamando o set()método. Isso também interromperá o thread filho:

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

Parando um thread que usa uma classe filha da classe Thread

Às vezes, você pode querer estender a Threadclasse e substituir o run()método para criar um novo thread:

class MyThread(Thread):
    def run(self):
        passLinguagem de código:  Python  ( python )

Para interromper o thread que usa uma classe derivada da Threadclasse, você também usa o Eventobjeto do módulo threading.

O exemplo a seguir mostra como criar um thread filho usando uma classe derivada da Threadclasse e usa o Eventobjeto para interromper o thread filho do thread principal em demanda:

from threading import Thread, Event
from time import sleep

class Worker(Thread):
    def __init__(self, event, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.event = event

    def run(self) -> None:
        for i in range(6):
            print(f'Running #{i+1}')
            sleep(1)
            if self.event.is_set():
                print('The thread was stopped prematurely.')
                break
        else:
            print('The thread was stopped maturely.')

def main() -> None:

    # create a new Event object
    event = Event()

    # create a new Worker thread
    thread = Worker(event)
    
    # start the thread
    thread.start()

    # suspend  the thread after 3 seconds
    sleep(3)

    # stop the child thread
    event.set()    
   

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

Como funciona.

Primeiro, defina uma Workerclasse que estenda a Threadclasse do módulo de threading. O __init__()método da Workerclasse aceita um Eventobjeto.

Segundo, substitua o run()método da Workerclasse e use o objeto de evento para interromper o thread.

Terceiro, defina a main()função que cria um evento, um Workerthread, e passa o objeto de evento para o Workerthread. A lógica restante é a mesma da main()função do exemplo anterior.

Resumo

  • Use o Eventobjeto para interromper um thread filho.
  • Use o set()método para definir um sinalizador interno de um Eventobjeto como True.
  • Use o is_set()método para verificar se o sinalizador interno de um Eventobjeto foi definido.

Deixe um comentário

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