Python erbjuder flera sätt att parallellisera för slingor, var och en med sina egna styrkor och svagheter. Det bästa valet beror på arten av arbetet i slingan och den tillgängliga hårdvaran.
1. `Multiprocessing`: Detta är i allmänhet det bästa valet för CPU-bundna uppgifter (uppgifter som tillbringar större delen av sin tid på att göra beräkningar). Det skapar flera processer, var och en med sin egen tolk, vilket möjliggör verklig parallellism och förbigår den globala tolklåset (GIL) som begränsar gängning i CPython.
`` `python
importera multiprocessing
DEF Process_Item (artikel):
"" "Den funktion som ska köras parallellt." ""
# Din kod för att behandla ett enda objekt går här.
resultat =artikel * 2 # Exempel:Dubbel objektet
avkastningsresultat
om __name__ =='__main__':# viktigt för Windows -kompatibilitet
artiklar =intervall (10)
med multiprocessing.pool (processer =multiprocessing.cpu_count ()) som pool:
resultat =pool.map (process_item, objekt)
utskrift (resultat)
`` `
* `Multiprocessing.Pool` skapar en pool av arbetarprocesser.
* `Pool.map` gäller` Process_Item` för varje objekt i `artiklar 'samtidigt. Den returnerar en lista över resultaten i samma ordning som ingången.
* `multiprocessing.cpu_count ()` bestämmer antalet CPU -kärnor, vilket möjliggör optimal parallellism. Du kan ange ett mindre antal processer om det behövs.
2. `Concurrent.Futures`: Detta ger ett gränssnitt på högre nivå till både trådar och processer, vilket erbjuder mer flexibilitet. För CPU-bundna uppgifter vill du använda "ProcessPoolExecutor".
`` `python
importera samtidiga.
DEF Process_Item (artikel):
"" "Den funktion som ska köras parallellt." ""
# Din kod för att behandla ett enda objekt går här.
resultat =artikel * 2 # Exempel:Dubbel objektet
returnera objekt, resultat #return både inmatning och utgång för att spåra
om __name__ =='__main__':
artiklar =intervall (10)
med samtidiga.futures.processpoolExecutor () som exekutiv:
resultat =executor.map (process_item, objekt) #Order bevarade
För objekt, resultera i resultat:
utskrift (f "input:{item}, output:{result}")
`` `
`Samtidig.Futures 'erbjuder mer kontroll, särskilt med` exekutiv.Submit' för enskilda uppgifter och hantering av undantag.
3. `Tråd '(rekommenderas vanligtvis inte för CPU-bundna uppgifter): Trådning är lämplig för I/O-bundna uppgifter (uppgifter som tillbringar större delen av sin tid på att vänta på externa resurser som nätverksförfrågningar eller diskoperationer). På grund av GIL ger trådarna i CPython inte verklig parallellism för CPU-bundna uppgifter.
`` `python
importtrådning
def process_item (objekt, resultat):
#Din kod för att behandla ett enda objekt går här.
resultat =artikel * 2 #example:dubbel objektet
resultat.Append (resultat)
om __name__ =='__main__':
artiklar =intervall (10)
resultat =[]
trådar =[]
För objekt i artiklar:
tråd =tråd. Thread (mål =process_item, args =(objekt, resultat))
trådar.Append (tråd)
tråd.start ()
För tråd i trådar:
tråd.join ()
utskrift (resultat)
`` `
Detta exempel använder en delad lista ("resultat") som behöver noggrant övervägande för trådsäkerhet (med lås vid behov). Det är mer komplicerat än "multiprocessing" eller "samtidiga.Futures" för CPU-bundna arbetsbelastningar och kommer sannolikt inte att ge ett prestationsökning för dem.
Att välja rätt metod:
* cpu-bundet: Använd `multiprocessing` eller` samtidig. `Multiprocessing 'är i allmänhet enklare för enkla driftsoperationer.
* i/o-bundet: Använd `gängan 'eller` concurrent.futures' med `ThreadPoolExecutor '. `Samtidig.Futures 'erbjuder bättre undantagshantering och kontroll.
* blandat: En hybridmetod kan vara nödvändig och kombinera processer för CPU-intensiva delar och trådar för I/O-bundna delar.
Kom ihåg att hantera potentiella undantag inom dina arbetarfunktioner och överväga omkostnaderna för att skapa och hantera processer eller trådar. För mycket små uppgifter kan omkostnaderna uppväga fördelarna med parallellisering. Profilera din kod för att avgöra om parallellisering faktiskt ger en prestationsförbättring.