1. Χρησιμοποιώντας `multiprocessing`: Αυτή είναι γενικά η καλύτερη προσέγγιση για εργασίες που συνδέονται με την CPU (εργασίες που ξοδεύουν το μεγαλύτερο μέρος του χρόνου τους να κάνουν υπολογισμούς). Δημιουργεί πολλαπλές διαδικασίες, καθένα από τα οποία εκτελεί ένα τμήμα του βρόχου.
`` `Python
Εισαγωγή πολλαπλής επεξεργασίας
def process_item (στοιχείο):
"" "Η λειτουργία που πρέπει να εφαρμοστεί σε κάθε στοιχείο στον βρόχο." ""
# Ο κωδικός σας για να επεξεργαστείτε ένα μόνο στοιχείο πηγαίνει εδώ
Αποτέλεσμα =Στοιχείο * 2 # Παράδειγμα:διπλασιάστε το στοιχείο
αποτέλεσμα επιστροφής
Εάν __name__ =='__main__':# Σημαντικό για τη συμβατότητα των Windows
Στοιχεία =Λίστα (εύρος (1000)) # Παράδειγμα Λίστα στοιχείων
με multiprocessing.pool (διαδικασίες =multiprocessing.cpu_count ()) ως πισίνα:
Αποτελέσματα =pool.map (process_item, αντικείμενα)
εκτύπωση (αποτελέσματα)
`` `
* `multiprocessing.pool`: Δημιουργεί μια δεξαμενή διαδικασιών εργαζομένων. `multiprocessing.cpu_count ()` Καθορίζει τον βέλτιστο αριθμό διαδικασιών που βασίζονται στους πυρήνες του συστήματός σας. Μπορείτε να προσαρμόσετε αυτόν τον αριθμό εάν χρειαστεί.
* `pool.map`: Εφαρμόζει τη λειτουργία `process_item` σε κάθε στοιχείο στα 'στοιχεία' Itable. Διαχειρίζεται τη διανομή του έργου και τη συλλογή των αποτελεσμάτων αποτελεσματικά.
* αν __name__ =='__main __':`: Αυτό είναι κρίσιμο, ειδικά στα Windows, για να αποτρέψει την δημιουργία πολλαπλών διαδικασιών αναδρομικά.
2. Χρησιμοποιώντας `concurrent.futures`: Παρέχει διεπαφή υψηλότερου επιπέδου για πολλαπλές επεξεργασίες και σπειρώματα, προσφέροντας μεγαλύτερη ευελιξία.
`` `Python
Εισαγωγή ταυτόχρονα.
def process_item (στοιχείο):
"" "Η λειτουργία που πρέπει να εφαρμοστεί σε κάθε στοιχείο στον βρόχο." ""
# Ο κωδικός σας για να επεξεργαστείτε ένα μόνο στοιχείο πηγαίνει εδώ
Αποτέλεσμα =Στοιχείο * 2 # Παράδειγμα:διπλασιάστε το στοιχείο
αποτέλεσμα επιστροφής
Εάν __name__ =='__main__':
Στοιχεία =Λίστα (εύρος (1000))
με ταυτόχρονα.
Αποτελέσματα =Λίστα (executor.map (process_item, αντικείμενα))
εκτύπωση (αποτελέσματα)
`` `
Αυτό είναι πολύ παρόμοιο με το `multiprocessing`, αλλά συχνά θεωρείται πιο πυθονική και ευκολότερη στη χρήση. Οι διαδικασίες "ProcessPoolExecutor" χρησιμοποιούν, ενώ το `threadPoolExecutor` χρησιμοποιεί τα νήματα (καλύτερα για εργασίες που συνδέονται με I/O).
3. Χρησιμοποιώντας `threading` (για εργασίες I/O-Bound): Εάν ο βρόχος σας περιλαμβάνει πολλή αναμονή (π.χ. αιτήματα δικτύου, αρχείο I/O), τα νήματα μπορεί να είναι πιο αποτελεσματικά από τις διαδικασίες. Ωστόσο, η παγκόσμια κλειδαριά διερμηνέα (GIL) στο CPYTHON περιορίζει τον πραγματικό παραλληλισμό για τις εργασίες που συνδέονται με την CPU μέσα σε νήματα.
`` `Python
Εισαγωγή σπειρώματος
def process_item (στοιχείο, αποτελέσματα):
"" "Η λειτουργία που πρέπει να εφαρμοστεί σε κάθε στοιχείο στον βρόχο." ""
# Ο κωδικός σας για να επεξεργαστείτε ένα μόνο στοιχείο πηγαίνει εδώ
Αποτέλεσμα =Στοιχείο * 2 # Παράδειγμα:διπλασιάστε το στοιχείο
αποτελέσματα.
Εάν __name__ =='__main__':
Στοιχεία =Λίστα (εύρος (1000))
Αποτελέσματα =[]
νήματα =[]
για αντικείμενο σε αντικείμενα:
Thread =Threading.Thread (Target =Process_Item, Args =(στοιχείο, αποτελέσματα))
threads.append (νήμα)
Thread.start ()
για νήμα σε νήματα:
Thread.join ()
εκτύπωση (αποτελέσματα)
`` `
Αυτό το παράδειγμα είναι πιο περίπλοκο επειδή πρέπει να διαχειριστείτε ρητά μια λίστα κοινόχρηστων αποτελεσμάτων. `concurrent.futures.ThreadPoolExecutor` απλοποιεί αυτό σημαντικά.
Επιλέγοντας τη σωστή μέθοδο:
* CPU-Bound: Χρησιμοποιήστε `multiprocessing` ή` concurrent.futures.processpoolexecutor`. Διαδικασίες παρακάμπτονται το GIL και επιτρέπουν τον πραγματικό παραλληλισμό.
* I/O-Bound: Χρησιμοποιήστε το `concurrent.futures.threadpoolExecutor`. Τα νήματα είναι ελαφρύτερο βάρος από τις διαδικασίες και η επιβάρυνση της εναλλαγής περιβάλλοντος είναι χαμηλότερη. Εάν το I/O είναι πολύ αργό, αυτό μπορεί να βελτιώσει την απόδοση ακόμη και με το GIL.
* Mixed: Εάν ο βρόχος σας έχει και τα δύο εξαρτήματα που συνδέονται με την CPU και τα δεσμευμένα σε I/O, μπορεί να χρειαστείτε μια πιο εξελιγμένη προσέγγιση, να συνδυάσετε ενδεχομένως τα νήματα και τις διαδικασίες ή τη χρήση ασύγχρονου προγραμματισμού (π.χ. `asyncio ').
Σημαντικές εκτιμήσεις:
* overhead: Η δημιουργία και η διαχείριση των διαδικασιών ή των νημάτων εισάγει γενικά έξοδα. Η παραλληλισμός παρέχει μόνο ένα όφελος εάν η εργασία που γίνεται ανά αντικείμενο είναι αρκετά σημαντική για να αντισταθμίσει αυτό το γενικό κόστος.
* Κοινή χρήση δεδομένων: Η κοινή χρήση δεδομένων μεταξύ των διαδικασιών είναι πιο περίπλοκη από την ανταλλαγή δεδομένων μεταξύ των νημάτων. Εξετάστε τη χρήση ουρών ή άλλων μηχανισμών επικοινωνίας μεταξύ της επεξεργασίας εάν είναι απαραίτητο.
* Debugging: Ο παράλληλος κώδικας εντοπισμού σφαλμάτων μπορεί να είναι προκλητική. Ξεκινήστε με μικρά παραδείγματα και αυξήστε σταδιακά την πολυπλοκότητα.
Θυμηθείτε να προφύσετε τον κωδικό σας για να μετρήσετε τη βελτίωση της απόδοσης μετά την παραλληλισμό. Είναι πιθανό ότι ο παραλληλισμός δεν παρέχει σημαντικό όφελος ή ακόμα και επιβραδύνει τα πράγματα, εάν το γενικό κόστος είναι πολύ υψηλό ή η εργασία δεν είναι κατάλληλη για παραλληλισμό.
Πνευματικά δικαιώματα © Γνώση Υπολογιστών Όλα τα δικαιώματα κατοχυρωμένα