Je kunt een standaard `for`-lus in Python niet direct parallelliseren met alleen de ingebouwde `for`-lusconstructie. Python's Global Interpreter Lock (GIL) voorkomt dat meerdere threads Python-bytecodes tegelijkertijd binnen één proces uitvoeren. Dit betekent dat echt parallellisme voor CPU-gebonden taken binnen een 'for'-lus onmogelijk is met alleen maar threading.
U kunt echter parallellisme bereiken met behulp van multiprocessing, waarbij de GIL wordt omzeild door meerdere processen te creëren. Hier ziet u hoe u parallelle verwerking in Python kunt implementeren met behulp van een `for`-lus en de `multiprocessing`-bibliotheek:
Methode 1:`multiprocessing.Pool.map` gebruiken (het eenvoudigst voor veel identieke bewerkingen)
Dit is de gemakkelijkste aanpak als elke iteratie van uw lus dezelfde bewerking op verschillende gegevens uitvoert. `Pool.map` verdeelt het werk efficiënt over meerdere processen.
```python
multiprocessing importeren
def proces_item(item):
"""De functie die voor elk item parallel moet worden uitgevoerd."""
# Hier vindt u uw code om één item te verwerken
# ... wat berekeningen ...
return result # Retourneert het resultaat van de berekening
if __name__ =='__main__':# Belangrijk voor Windows-compatibiliteit
gegevens =[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Uw gegevens
met multiprocessing.Pool(processes=multiprocessing.cpu_count()) als pool:
resultaten =pool.map(process_item, data)
afdrukken(resultaten)
```
Met deze code wordt een pool van werkprocessen gemaakt (standaard gelijk aan het aantal CPU-kernen). `pool.map` past gelijktijdig `process_item` toe op elk element in `data`, en retourneert een lijst met resultaten in dezelfde volgorde als de invoer.
Methode 2:`multiprocessing.Pool.apply_async` gebruiken (voor complexere scenario's of asynchrone bewerkingen)
Als uw lus complexere logica of asynchrone bewerkingen omvat, biedt `apply_async` meer controle.
```python
multiprocessing importeren
def proces_item(item):
# ...uw code ...
resultaat terug
als __naam__ =='__hoofd__':
gegevens =[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
resultaten =[]
met multiprocessing.Pool(processes=multiprocessing.cpu_count()) als pool:
# apply_async retourneert een AsyncResult-object
async_results =[pool.apply_async(process_item, (item,)) voor item in gegevens]
# Ontvang de resultaten (blokkeren totdat alle processen zijn voltooid)
voor async_result in async_results:
resultaten.append(async_result.get())
afdrukken(resultaten)
```
Met `apply_async` kunt u taken afzonderlijk indienen en de resultaten later ophalen. Dit is handig als de verwerkingstijd per item aanzienlijk varieert.
Belangrijke overwegingen:
* `if __name__ =='__main__':`: Dit is cruciaal, vooral op Windows, om het creëren van recursieve processen te voorkomen.
* Gegevens delen: Vermijd het rechtstreeks delen van veranderlijke gegevens tussen processen. Gebruik technieken zoals wachtrijen of pijpen voor communicatie tussen processen om race-condities te voorkomen.
* Overhead: Het creëren en beheren van processen heeft overhead. Parallelle verwerking is het meest gunstig voor rekenintensieve taken waarbij de verwerkingstijd aanzienlijk groter is dan de overhead.
* Aantal processen: Het optimale aantal processen is vaak gelijk aan het aantal CPU-kernen, maar experimenteren kan nodig zijn.
Vergeet niet om `# ... uw code...` te vervangen door uw werkelijke berekening. Kies de methode die het beste past bij de structuur en complexiteit van de bewerkingen van uw `for`-lus. Voor eenvoudige, parallel-vriendelijke bewerkingen heeft `Pool.map` doorgaans de voorkeur en meest efficiënte aanpak. |