multiprocessing vs multithreading vs asyncio in Python 3


105

Ho scoperto che in Python 3.4 ci sono poche librerie differenti per multiprocessing / threading: multiprocessing vs threading vs asyncio .

Ma non so quale usare o è "consigliato". Fanno la stessa cosa o sono diversi? In caso affermativo, quale viene utilizzato per cosa? Voglio scrivere un programma che utilizzi multicore nel mio computer. Ma non so quale libreria dovrei imparare.


Risposte:


79

Sono destinati a scopi e / o requisiti (leggermente) diversi. CPython (un'implementazione tipica di Python principale) ha ancora il blocco dell'interprete globale, quindi un'applicazione multi-thread (un modo standard per implementare l'elaborazione parallela al giorno d'oggi) non è ottimale. Ecco perché multiprocessing potrebbe essere preferito threading. Ma non tutti i problemi possono essere efficacemente suddivisi in parti [quasi indipendenti], quindi potrebbe esserci bisogno di comunicazioni tra processi pesanti. Ecco perché multiprocessingpotrebbe non essere preferito threadingin generale.

asyncio(questa tecnica è disponibile non solo in Python, ma anche in altri linguaggi e / o framework, ad esempio Boost.ASIO ) è un metodo per gestire efficacemente molte operazioni di I / O da molte fonti simultanee senza bisogno di esecuzione parallela di codice . Quindi è solo una soluzione (davvero buona!) Per un compito particolare, non per l'elaborazione parallela in generale.


7
Notando che sebbene tutti e tre possano non raggiungere il parallelismo, sono tutti in grado di eseguire attività simultanee (non bloccanti).
sargas

65

[Risposta rapida]

TL; DR

Fare la scelta giusta:

Abbiamo esaminato le forme più popolari di concorrenza. Ma la domanda rimane: quando scegliere quale? Dipende davvero dai casi d'uso. Dalla mia esperienza (e lettura), tendo a seguire questo pseudo codice:

if io_bound:
    if io_very_slow:
        print("Use Asyncio")
    else:
        print("Use Threads")
else:
    print("Multi Processing")
  • CPU Bound => Multi Processing
  • I / O limitato, I / O veloce, numero limitato di connessioni => Multi Threading
  • I / O vincolato, I / O lento, molte connessioni => Asyncio

Riferimento


[ NOTA ]:

  • Se hai un metodo di chiamata lunga (cioè un metodo che conteneva un tempo di sospensione o un I / O pigro), la scelta migliore è l' approccio asyncio , Twisted o Tornado (metodi coroutine), che funziona con un singolo thread come concorrenza.
  • asyncio funziona su Python3.4 e versioni successive.
  • Tornado e Twisted sono pronti da Python2.7
  • uvloop è un asyncioloop di eventi ultraveloce ( uvloop rende asyncio2-4 volte più veloce).

[AGGIORNAMENTO (2019)]:

  • Japranto ( GitHub ) è un server HTTP pipelining molto veloce basato su uvloop .

Quindi se ho un elenco di URL da richiedere, è meglio usare Asyncio ?
mingchau

1
@mingchau, Sì, ma tieni presente che potresti usare da asyncioquando usi da funzioni awaitable, la requestlibreria non è un metodo attendibile, invece di che puoi usare come la aiohttplibreria o la richiesta asincrona e così via
Benyamin Jafari,

si prega di estendere su slowIO e fastIO per andare multithread o asyncio>?
qrtLs

@qrtLs Quando hai uno SlowIO, AsyncIO è molto utile e più efficiente.
Benyamin Jafari

1
@variable I / O bound significa che il programma trascorre la maggior parte del tempo a parlare con un dispositivo lento, come una connessione di rete, un disco rigido, una stampante o un ciclo di eventi con un tempo di sospensione. Quindi in modalità di blocco, puoi scegliere tra threading o asyncio, e se la tua sezione di delimitazione è molto lenta, il multitasking cooperativo (asyncio) è una scelta migliore (cioè evitare la fame di risorse, dead-lock e condizioni di gara)
Benyamin Jafari

8

Questa è l'idea di base:

È IO- BOUND? ---------> UTILIZZOasyncio

È CPU- PESANTE? -----> USAmultiprocessing

ALTRO ? ----------------------> UTILIZZOthreading

Quindi fondamentalmente attenersi al threading a meno che non si abbiano problemi di IO / CPU.


0

Nel multiprocessing puoi sfruttare più CPU per distribuire i tuoi calcoli. Poiché ciascuna delle CPU funziona in parallelo, sei effettivamente in grado di eseguire più attività contemporaneamente. Si desidera utilizzare il multiprocessing per le attività legate alla CPU . Un esempio potrebbe essere il tentativo di calcolare una somma di tutti gli elementi di un elenco enorme. Se la tua macchina ha 8 core, puoi "tagliare" l'elenco in 8 elenchi più piccoli e calcolare la somma di ciascuno di quegli elenchi separatamente su core separati e poi sommare semplicemente quei numeri. Otterrai una velocità di ~ 8 volte in questo modo.

Nella filettaturanon hai bisogno di più CPU. Immagina un programma che invia molte richieste HTTP al web. Se si utilizza un programma a thread singolo, si interrompe l'esecuzione (blocco) ad ogni richiesta, si attende una risposta e quindi si continua una volta ricevuta la risposta. Il problema qui è che la tua CPU non sta realmente funzionando mentre aspetta che qualche server esterno faccia il lavoro; avrebbe potuto effettivamente svolgere un lavoro utile nel frattempo! La soluzione consiste nell'usare i thread: puoi crearne molti, ciascuno responsabile della richiesta di alcuni contenuti dal web. La cosa bella dei thread è che, anche se vengono eseguiti su una CPU, la CPU di tanto in tanto "blocca" l'esecuzione di un thread e passa all'esecuzione dell'altro (si chiama cambio di contesto e avviene costantemente a tempi non deterministici intervalli). - usa la filettatura.

asyncio è essenzialmente threading dove non la CPU ma tu, come programmatore (o effettivamente la tua applicazione), decidi dove e quando avviene il cambio di contesto . In Python usi una awaitparola chiave per sospendere l'esecuzione della tua coroutine (definita usando asyncparola chiave).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.