Answer the question
In order to leave comments, you need to log in
How to use asyncio inside Thread Python?
I have a pyqt5 application, inside the function of which I create threads through a modified class, in order to stop the thread at the request of the user. After that, asyncio is used inside the thread, which causes a conflict.
results=[]
def get_tasks(session):
tasks = []
for i in range(0,requestsNumber):
tasks.append(asyncio.create_task(session.post(url, data = json.dumps(js), ssl=False)))
return tasks
async def get_symbols(headers):
async with aiohttp.ClientSession(headers=headers) as session:
tasks = get_tasks(session)
responses = await asyncio.gather(*tasks)
for response in responses:
results.append(await response.text())
def startSsc(headers):
asyncio.get_event_loop().run_until_complete(get_symbols(headers))
class thread_with_exception(threading.Thread):
def __init__(self,name):
threading.Thread.__init__(self)
self.name = name
def run(self):
#some code (основная функция для запуска в многопоточности)
startSsc(head)
def get_id(self):
# returns id of the respective thread
if hasattr(self, '_thread_id'):
return self._thread_id
for id, thread in threading._active.items():
if thread is self:
return id
def raise_exception(self):
thread_id = self.get_id()
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id,
ctypes.py_object(SystemExit))
if res > 1:
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0)
print('Exception raise failure')
class Ui_Dialog(object):
def setupUi(self,code,end, Dialog):
#some code
def start(self):
s = thread_with_exception(some_args)
s.start()
self.ap[i]=s
def stop_all_tasks(self):
for i in self.ap:
self.ap[i].raise_exception()
self.ap[i].join()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(code,end,MainWindow)
MainWindow.show()
sys.exit(app.exec_())
RuntimeError("There is no current event loop in thread '0'.")
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
ClientOSError(22, 'Указанное сетевое имя более недоступно', None, 64, None)
Answer the question
In order to leave comments, you need to log in
First, several asynchronous tasks coexist perfectly with each other. Why do you even need threads for this? What's wrong with loop.create_task(), or asyncio.gather()?
Secondly, it is much easier to wrap a long synchronous code into a thread, and already a thread into an asynchronous task, than vice versa. Think about it.
Thirdly, technically you can create your own reactor loop (asyncio loop) in each thread. Read the asyncio docs on how to do this. But you need to remember that async objects from different reactors are not friendly with each other. So I emphasize in red: do not do this . It is better to first try to approach the problem in a different way.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question