Modul `concurrent` dalam Python
Dalam artikel ini, kami akan menerangkan modul concurrent dalam Python.
Sambil memperjelaskan konsep keserentakan dan selari, kami akan menerangkan cara melaksanakan pemprosesan asinkron menggunakan modul concurrent dengan contoh praktikal.
YouTube Video
Modul concurrent dalam Python
Apabila mempercepatkan pemprosesan dalam Python, adalah penting untuk memahami perbezaan antara keserentakan dan pemprosesan selari. Modul concurrent adalah cara penting untuk mengendalikan pemprosesan asinkron secara selamat dan mudah dengan mengambil kira perbezaan ini.
Perbezaan Antara Keserentakan dan Selari
-
Keserentakan bermaksud mereka bentuk proses supaya pelbagai tugas dijalankan dengan beralih antara satu sama lain dalam unit kerja yang kecil. Walaupun tugas tidak dijalankan serentak, menggunakan 'masa menunggu' membolehkan anda menjadikan keseluruhan proses lebih cekap.
-
Selari ialah mekanisme yang melaksanakan pelbagai tugas secara fizikal pada masa yang sama. Dengan menggunakan pelbagai teras CPU, pemprosesan boleh dijalankan secara serentak.
Kedua-duanya adalah teknik untuk mempercepatkan pemprosesan, tetapi keserentakan adalah isu reka bentuk tentang 'cara untuk menjalankan,' manakala selari adalah isu pelaksanaan tentang 'bagaimana ia dijalankan,' menjadikan kedua-duanya berbeza pada asasnya.
Apakah Modul concurrent?
concurrent ialah pustaka standard dalam Python yang menyediakan API peringkat tinggi untuk mengendalikan keserentakan dan selari dengan selamat dan mudah. Ia direka supaya anda boleh memfokuskan pada 'melaksanakan tugas' tanpa perlu risau tentang operasi peringkat rendah seperti penciptaan dan pengurusan thread atau proses.
Peranan ThreadPoolExecutor dan ProcessPoolExecutor
Modul concurrent menyediakan dua pilihan utama bergantung pada sifat tugas.
-
ThreadPoolExecutorIni sesuai untuk pelaksanaan keserentakan, terutamanya untuk tugas yang mempunyai banyak masa menunggu I/O, seperti operasi rangkaian atau fail. Dengan beralih antara tugas, ia dapat menggunakan masa menunggu dengan berkesan. -
ProcessPoolExecutorPelaksanaan ini ditujukan untuk pemprosesan selari dan sesuai untuk tugas yang memerlukan penggunaan CPU yang intensif. Ia menggunakan pelbagai proses untuk memanfaatkan sepenuhnya teras CPU yang tersedia secara selari.
Oleh itu, ciri utama modul concurrent ialah ia menyediakan struktur yang membolehkan anda memilih dengan betul antara keserentakan dan selari mengikut keperluan.
Asas ThreadPoolExecutor (Untuk Tugas I/O)
ThreadPoolExecutor sesuai untuk tugas berasaskan I/O, seperti komunikasi rangkaian dan operasi fail. Ia mengagihkan tugas antara pelbagai thread, menjadikan masa menunggu digunakan dengan lebih berkesan.
1from concurrent.futures import ThreadPoolExecutor
2import time
3
4def fetch_data(n):
5 # Simulate an I/O-bound task
6 time.sleep(1)
7 return f"data-{n}"
8
9with ThreadPoolExecutor(max_workers=3) as executor:
10 futures = [executor.submit(fetch_data, i) for i in range(5)]
11
12 for future in futures:
13 print(future.result())- Dalam contoh ini, beberapa tugas I/O yang menunggu selama satu saat dijalankan secara serentak. Dengan menggunakan
submit, panggilan fungsi didaftarkan sebagai tugas asinkron, dan dengan memanggilresult(), anda boleh menunggu siap dan mendapatkan hasilnya, membolehkan anda melaksanakan pemprosesan serentak yang menggunakan masa menunggu dengan berkesan secara ringkas.
Keserentakan Mudah Menggunakan map
Jika kawalan yang kompleks tidak diperlukan, menggunakan map boleh menjadikan kod anda lebih ringkas.
1from concurrent.futures import ThreadPoolExecutor
2import time
3
4def fetch_data(n):
5 # Simulate an I/O-bound task
6 time.sleep(1)
7 return f"data-{n}"
8
9with ThreadPoolExecutor(max_workers=3) as executor:
10 results = executor.map(fetch_data, range(5))
11
12 for result in results:
13 print(result)- Dalam contoh ini, beberapa tugas I/O dijalankan secara serentak menggunakan
ThreadPoolExecutor.map. Oleh keranamapmengembalikan hasil dalam susunan yang sama seperti input, anda boleh menulis kod yang hampir dengan pemprosesan berurutan, dan pelaksanaan serentak boleh dilakukan tanpa perlu memikirkan pemprosesan asinkron—ini adalah kelebihan utama.
Asas ProcessPoolExecutor (Untuk Tugas Berat CPU)
Untuk pengiraan berat yang benar-benar menggunakan CPU, anda harus menggunakan proses berbanding thread. Ini membolehkan anda mengelakkan had Global Interpreter Lock (GIL).
1from concurrent.futures import ProcessPoolExecutor
2
3def heavy_calculation(n):
4 # Simulate a CPU-bound task
5 total = 0
6 for i in range(10_000_000):
7 total += i * n
8 return total
9
10if __name__ == "__main__":
11 with ProcessPoolExecutor(max_workers=4) as executor:
12 results = executor.map(heavy_calculation, range(4))
13
14 for result in results:
15 print(result)Dalam contoh ini, pengiraan yang memerlukan CPU dijalankan secara selari menggunakan ProcessPoolExecutor. Disebabkan penciptaan proses terlibat, pengawal __main__ diperlukan, yang membolehkan pemprosesan selari yang selamat menggunakan pelbagai teras CPU.
Pemprosesan Mengikut Urutan Selesai Menggunakan as_completed
as_completed berguna apabila anda ingin mengendalikan hasil mengikut urutan mereka siap.
1from concurrent.futures import ThreadPoolExecutor, as_completed
2import time
3
4def fetch_data(n):
5 # Simulate an I/O-bound task
6 time.sleep(1)
7 return f"data-{n}"
8
9with ThreadPoolExecutor(max_workers=3) as executor:
10 futures = [executor.submit(fetch_data, i) for i in range(5)]
11
12 for future in as_completed(futures):
13 print(future.result())- Dalam contoh ini, beberapa tugas asinkron dijalankan serentak, dan hasil diperoleh mengikut urutan tugas itu siap. Menggunakan
as_completedmembolehkan anda mengurus hasil dengan cepat tanpa mengira susunan tugas, menjadikannya sesuai untuk paparan kemajuan atau situasi yang memerlukan pengurusan berurutan.
Mengendalikan Pengecualian
Dalam concurrent, pengecualian akan ditimbulkan apabila anda memanggil result().
1from concurrent.futures import ThreadPoolExecutor
2
3def risky_task(n):
4 # Simulate a task that may fail for a specific input
5 if n == 3:
6 raise ValueError("Something went wrong")
7 return n * 2
8
9with ThreadPoolExecutor() as executor:
10 futures = [executor.submit(risky_task, i) for i in range(5)]
11
12 for future in futures:
13 try:
14 print(future.result())
15 except Exception as e:
16 print("Error:", e)- Contoh ini menunjukkan bahawa walaupun ada tugas yang menimbulkan pengecualian, tugas lain masih diteruskan dan anda boleh mengendalikan pengecualian satu per satu ketika mendapat hasil. Dengan menggunakan
Futuredalamconcurrent, adalah penting supaya kejayaan dan kegagalan dalam pemprosesan asinkron dapat dikendalikan dengan selamat.
Garis Panduan untuk Memilih Antara Thread dan Proses
Untuk menggunakan keserentakan dan selari dengan berkesan, adalah penting memilih pendekatan yang betul berdasarkan sifat tugas.
Dalam praktik, kriteria berikut dapat membantu anda membuat keputusan.
- Untuk proses yang mempunyai banyak masa menunggu I/O, seperti komunikasi atau operasi fail, gunakan
ThreadPoolExecutor. - Untuk tugas berat CPU dan pengiraan berat, gunakan
ProcessPoolExecutor. - Jika terdapat banyak tugas mudah, menggunakan
mapmembolehkan anda menulis kod yang lebih ringkas. - Jika kawalan terperinci terhadap urutan pelaksanaan atau pengendalian pengecualian penting, gabungkan
submitdenganas_completed.
Kelebihan Menggunakan concurrent
Dengan menggunakan modul concurrent, anda boleh mengendalikan pemprosesan asinkron dengan selamat dan intuitif.
Kelebihan utamanya adalah seperti berikut:.
- Anda tidak perlu risau tentang pengurusan thread atau proses peringkat rendah.
- Ia disediakan sebagai sebahagian daripada pustaka standard Python, jadi anda boleh menggunakannya dengan yakin.
- Kod menjadi lebih mudah dibaca dan diselenggara.
- Ia sesuai sebagai langkah pertama untuk mempelajari tentang keserentakan dan selari.
Hanya dengan mengingati garis panduan ini boleh mengurangkan kegagalan dalam pelaksanaan menggunakan concurrent.
Ringkasan
Modul concurrent ialah pilihan standard untuk keserentakan dan selari secara praktikal dalam Python. Ia membolehkan anda meningkatkan prestasi tanpa banyak mengubah kandungan pemprosesan anda, yang merupakan faedah besar dalam amalan sebenar. Dengan menggunakan concurrent, anda boleh melaksanakan pemprosesan asinkron dengan ringkas sambil mengurus pengendalian pengecualian dan kawalan pelaksanaan dengan selamat.
Anda boleh mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Sila lihat juga saluran YouTube kami.