Home > Back-end >  How to run an async forever thread together with other threads in Python?
How to run an async forever thread together with other threads in Python?

Time:06-13

I'm trying to run an async run_forever together with other threads. But I only get output from the forever thread, making me think that the second thread doesn't even start.

Code - Classes.py:

import asyncio

class Class1:
    def __init__(self):
        self.loop = asyncio.get_event_loop()

    async def _funcClass1(self):
        while True:
            await asyncio.sleep(5)
            print('Hello async/threading world')

    def funcClass1(self):
        asyncio.ensure_future(self._funcClass1())
        self.loop.run_forever()

class Class2:
    def __init__(self):
        self.loop = asyncio.get_event_loop()
    
    async def _funcClass2(self, name):
        print(f'Hello {name}')
    
    def funcClass2(self):
        self.loop.run_until_complete(self._funcClass2())

Code - main.py:

from Classes import Class1, Class2
import threading
import asyncio

class1 = Class1()
class2 = Class2()

if __name__ == "__main__":
    t1 = threading.Thread(target=asyncio.run, args=(class1.funcClass1(), ))
    t2 = threading.Thread(target=class2.funcClass2, args=('john', ))

    t1.start()
    t2.start()

    t1.join()
    t2.join()

Output:

Hello async/threading world
Hello async/threading world
Hello async/threading world
Hello async/threading world
Hello async/threading world
Hello async/threading world
Hello async/threading world
Hello async/threading world
Hello async/threading world

CodePudding user response:

run_forever() will block the next lines of code.

try to put it after running the 2nd thread

classes.py

import asyncio

class Class1:
    def __init__(self):
        self.loop = asyncio.get_event_loop()

    async def _funcClass1(self):
        while True:
            await asyncio.sleep(5)
            print('Hello async/threading world')

    def funcClass1(self):
        asyncio.ensure_future(self._funcClass1())

class Class2:
    def __init__(self):
        self.loop = asyncio.get_event_loop()
    
    async def _funcClass2(self, name):
        print(f'Hello {name}')
    
    def funcClass2(self):
        self.loop.run_until_complete(self._funcClass2())

main.py

from Classes import Class1, Class2
import threading
import asyncio

class1 = Class1()
class2 = Class2()

if __name__ == "__main__":
    t1 = threading.Thread(target=asyncio.run, args=(class1.funcClass1(), ))
    t2 = threading.Thread(target=class2.funcClass2, args=('john', ))

    t1.start()
    t2.start()

    class1.loop.run_forever()

    t1.join()
    t2.join()

CodePudding user response:

After playing around with the answer of @danangjoyoo. I came up with this (both functions need to be executed as target=asyncio.run):

classes.py:

import asyncio

class Class1:
    def __init__(self):
        self.loop = asyncio.get_event_loop()

    async def _funcClass1(self):
        while True:
            await asyncio.sleep(5)
            print('Hello async/threading world')

    def funcClass1(self):
        asyncio.ensure_future(self._funcClass1())

class Class2:
    def __init__(self):
        self.loop = asyncio.get_event_loop()
    
    async def _funcClass2(self, name):
        print(f'Hello {name}')
    
    def funcClass2(self, name):
        asyncio.ensure_future(self._funcClass2(name))

main.py:

from Classes import Class1, Class2
import threading
import asyncio

class1 = Class1()
class2 = Class2()

if __name__ == "__main__":
    t1 = threading.Thread(target=asyncio.run, args=(class1.funcClass1()))
    t2 = threading.Thread(target=asyncio.run, args=(class2.funcClass2('john')))

    class1.loop.run_forever()
    class2.loop.run_until_complete()

    t1.start()
    t2.start()

    t1.join()
    t2.join()
  • Related