You can use the asyncio
, in which coroutines/tasks (Task
) are similar to threads but are not really threads as defined by the OS, and so have no problem changing context or state outside of their own program.
Suppose you want to square a list of numbers from 0 to 4, but want to cancel the 2 2 calculation if the result of some other function is 9, without having inside the corotine of calculation no check, as you requested.
I would do so with asyncio
:
import asyncio
import random
# Função que simula algum trabalho de cada tarefa/corotina (semelhante a uma thread)
async def retornar_quadrado(n):
if n == 2:
await asyncio.sleep(10) # A função que será cancelada demora mais.
else:
await asyncio.sleep(random.uniform(0.5, 2)) # As outras demoram de 0.5 a 2 segundos.
return n ** 2
async def main():
# Criar uma lista de tarefas
tarefas = []
for i in range(5):
tarefa = asyncio.ensure_future(retornar_quadrado(i))
tarefas.append(tarefa)
for tarefa_completa in asyncio.as_completed(tarefas):
try:
n_quadrado = await tarefa_completa
print(n_quadrado)
except asyncio.CancelledError:
continue
# Se descobrimos que uma das respostas é 9, cancelamos tarefas[2]
if n_quadrado == 9 and not tarefas[2].cancelled():
print('Cancelando tarefas[2]...')
tarefas[2].cancel()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
An example of a result:
16
9
Cancelando tarefas[2]...
0
1
As you can see, as soon as we found 9, we canceled the calculation of 2 2 and it was never displayed. Removing the line tarefas[2].cancel()
, you will see that the result 4
will be displayed, and also that the function will take the 10 seconds that this special case requires.
Ah, you want to abort the thread? Like, leave everything in an inconsistent state and just walk away from it? Good luck! :)
– Marcelo Shiniti Uchimura
@Marcelouchimura can make a little more constructive comment and tell us why this is a bad idea, and what problems can bring? (:
– Pedro von Hertwig Batista
Only those who can know what the state of the thread is the thread’s own execution flow. Any attempt to kill him out of context is the same thing as trying to take down a plane out of it.
– Marcelo Shiniti Uchimura
I need to finish a thread from a pre-configured timeout-free socket client to connect. The client is SSL. But sometimes the user inserts a non-SIP IP so the program claws at wrap_socket and by not having timeout pre configured remains Garrated for quite a while. The user can see that.
– user110265
I solved the problem. I put a 30-second timeout until connecting to the server, and once connected I removed the timeout on I/O and the loop loop can finish the thread when you want.
– user110265