简体   繁体   中英

Running Two classes for infinite for loops

I have two classes that both have for loops that go on forever. When creating a super I am unable to get the class Second to run due to class FIrst also looping. Here is some sudo code. I am at a loss of how to execute them both and have to them run at the same time.

class First:
    def one(self):
        for test1 in test2:
            # go on forever
            print('here is 2')


class Second:
    def two(self):
        for test3 in test4:
            # go on forever
            print('here is 2')


class SuperNumber(First, Second):
    pass


Foo = SuperNumber()
Foo.one()
Foo.two()

Whenever you want to do two things at once, you need concurrency . Python has a few options built-in for doing several things at once:

Using coroutines

This is sometimes called cooperative multitasking . Concurrency is all achieved in the main thread.

import asyncio

class First:
    async def one(self):
        while True:
            print('here is 1')
            await asyncio.sleep(0)

class Second:
    async def two(self):
        while True:
            print('here is 2')
            await asyncio.sleep(0)

class SuperNumber(First, Second):
    pass

foo = SuperNumber()
one = foo.one()
two = foo.two()

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(one, two))

That's similar to carrying on two conversations, with one person on the phone and another person face-to-face, by periodically asking each person to hold on a moment.

Using threading

This uses multiple threads, but still only one CPU. It's best suited to situations where we can benefit from the release of the GIL , eg IO-bound applications.

from concurrent.futures import ThreadPoolExecutor    

class First:
    def one(self):
        while True:
            print('here is 1')

class Second:
    def two(self):
        while True:
            print('here is 2')

class SuperNumber(First, Second):
    pass

foo = SuperNumber()

with ThreadPoolExecutor(max_workers=2) as executor:
    executor.submit(foo.one)
    executor.submit(foo.two)

That's similar to when you're cooking dinner, and you put the water on the stove, and then you chop up some vegetables whilst you're waiting for the water to boil. You [user] don't have to just sit there and watch the water boil, because that's the stove [kernel] job, so you may as well make yourself useful in the meantime.

Using multiprocessing

This uses multiple CPUs, and is the only solution here that can achieve true parallelism , so this approach is generally the best one for CPU-bound applications. Notice the code is exactly the same as the threading example, but just using a different executor class. It has the most overhead; you need a Python interpreter per-process, so it's more expensive to scale it up to multiple tasks.

from concurrent.futures import ProcessPoolExecutor

class First:
    def one(self):
        while True:
            print('here is 1')

class Second:
    def two(self):
        while True:
            print('here is 2')

class SuperNumber(First, Second):
    pass

foo = SuperNumber()

with ProcessPoolExecutor(max_workers=2) as executor:
    executor.submit(foo.one)
    executor.submit(foo.two)

That's similar to hiring a kitchen-hand to help you chop up vegetables while you chop up vegetables. You've got to buy another knife and chopping board, but you should be able to get the potatoes chopped in half the time this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM