Mam wielowątkową aplikację Pythona. Chcę uruchomić pętlę asyncio w wątku, a następnie opublikowac kalki i współprogramy z innego wątku. Powinno być łatwe, ale nie mogę się skupić na rzeczach asyncio.python asyncio, jak tworzyć i anulować zadania z innego wątku
wpadłem do następnego rozwiązania, które robi połowę tego, co chcę, czuć się swobodnie wypowiedzieć się na temat wszystkiego:
import asyncio
from threading import Thread
class B(Thread):
def __init__(self):
Thread.__init__(self)
self.loop = None
def run(self):
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop) #why do I need that??
self.loop.run_forever()
def stop(self):
self.loop.call_soon_threadsafe(self.loop.stop)
def add_task(self, coro):
"""this method should return a task object, that I
can cancel, not a handle"""
f = functools.partial(self.loop.create_task, coro)
return self.loop.call_soon_threadsafe(f)
def cancel_task(self, xx):
#no idea
@asyncio.coroutine
def test():
while True:
print("running")
yield from asyncio.sleep(1)
b.start()
time.sleep(1) #need to wait for loop to start
t = b.add_task(test())
time.sleep(10)
#here the program runs fine but how can I cancel the task?
b.stop()
Więc uruchamiania i zatrzymać pętlę działa dobrze. Myślałem o tworzeniu zadania przy użyciu create_task, ale ta metoda nie jest bezpieczna dla wątków, więc zapakowałem ją w call_soon_threadsafe. Ale chciałbym móc uzyskać obiekt zadania, aby móc anulować zadanie. Mogę zrobić skomplikowane rzeczy używając Future and Condition, ale musi być prostszy sposób, prawda?
Dzięki za przykład pomógł mi rozwiązać kilka problemów, które miałem. Btw także musiałem zainicjować Future with Future (loop = self.loop), inaczej w niektórych przypadkach przyszłość przyjąłaby niewłaściwą pętlę –
@OlivierRD Powinieneś używać 'concurrent.futures.Future', a nie' asyncio.Future'. 'concurrent.futures.Future' nie przyjmuje arytmetycznego słowa' loop'. – dano
Dokumentacja wydaje się mówić: https://docs.python.org/3/library/asyncio-task.html#asyncio.Future –