2017-03-28 2 views
1

erwartet ich ein ereignisbasiertes System benutzen die neuen Python 3.5 Koroutinen verwenden und warten. Ich registriere Ereignisse und diese Ereignisse werden vom System aufgerufen.Python Multiprocessing kontinuierliche Verarbeitung mit

@event 
aysnc def handleevent(args): 
    # handle the event 

Ich muss einige Klassen initialisieren, um die Arbeit zu erledigen (zeitaufwendig). Rufen Sie dann Instanzenmethoden auf, die ebenfalls zeitaufwendig sind (sie verwenden tatsächlich Selen, um bestimmte Sites zu durchsuchen).

Idealer Dieser Code

# supposedly since this is multiprocessing this is a different driver per process 
driver = None 
def init(): 
    # do the heavy initialization here 
    global driver 
    driver = webdriver.Chrome() 

def longworkmethod(): 
    ## need to return some data 
    return driver.dolongwork() 

class Drivers: 
""" A class to handle async and multiprocessing""" 
    def __init__(self, numberOfDrivers): 
     self.pool = multiprocessing.Pool(processes=numberOfDrivers, initializer=init)  

    async def dowork(self, args): 
     return self.pool.apply_async(longworkmethod, args=args) 


### my main python class 
drivers = Drivers(5) 

@event 
aysnc def handleevent(args): 
    await drivers.dowork(args) 

@event 
aysnc def quit(args): 
    ## do cleanup on drivers 
    sys.exit(0) 

so etwas wie der folgende Code nicht will arbeiten, ich würde, aber ich habe viele verschiedene Möglichkeiten, und keiner versucht, scheinen in der Lage zu tun, was ich will.

Es muss nicht diese genaue Form sein, aber wie gehe ich über die await und Koroutinen mit einem Programm, das Mischen, das Multiprocessing benötigt?

Antwort

2

Während es technisch nichts gibt, was Sie davon abhalten würde, asyncio und multiprocessing zu mischen, würde ich vorschlagen, dies zu vermeiden. Es wird eine Menge Komplexität hinzufügen, da Sie am Ende eine Ereignisschleife pro Thread benötigen und die Weitergabe von Informationen hin und her wird schwierig. Benutze einfach das eine oder das andere.

asyncio liefert Funktionen zum Ausführen von Aufgaben in einem anderen Thread - wie AbstractEventLoop.run_in_executor. Werfen Sie einen Blick auf diese Antworten

Alternativ können Sie nur multiprocessing verwenden, wie Selen eine blockierende (nicht asyncio) Schnittstelle hat, aber es klingt wie einige von Ihrem Code verwendet bereits mit asyncio so vielleicht mit dem oben genannten.

+0

Ich kann das Mischen nicht vermeiden, weil ich Selen (Multiprocessing) benötigen, und das Ereignissystem verwende ich streng asyncio. Aber ich werde diese Links überprüfen. Schau, ob ich sie arbeiten lassen kann. – leftsync

+0

Selen blockiert, aber das bedeutet nicht, dass Sie Multiprozessing benötigen. Verwenden Sie einfach 'run_in_executor' für die blockierenden Bits und behalten Sie alles andere in der Hauptthread/Ereignisschleife. –

+0

Diese Links scheinen also zu helfen. Sollte ich run_in_executor für einzelne teure Anrufe wie "get" benutzen, oder kann ich große teure Funktionen mit mehreren teuren Anrufen machen? Würde es einen Unterschied geben? – leftsync