Concurrency ialah idea penting dalam pengaturcaraan moden yang membenarkan berbilang tugasan dijalankan pada masa yang sama untuk meningkatkan prestasi aplikasi.
Terdapat beberapa cara untuk mencapai konkurensi dalam Python, dengan penjalinan dan pemprosesan berbilang adalah yang paling terkenal.
Dalam artikel ini, kami akan meneroka kedua-dua kaedah ini secara terperinci, memahami cara ia berfungsi dan membincangkan masa untuk menggunakan setiap kaedah, bersama-sama dengan contoh kod praktikal.
Sebelum kita bercakap tentang threading dan multiprocessing, adalah penting untuk memahami maksud concurrency.
Concurrency ialah apabila program boleh melakukan berbilang tugas atau proses pada masa yang sama.
Ini boleh menjadikan program menggunakan sumber lebih baik dan berjalan lebih pantas, terutamanya apabila ia perlu melakukan perkara seperti membaca fail atau melakukan banyak pengiraan.
Terdapat dua cara utama untuk mencapai keselarasan:
Python menawarkan dua cara utama untuk mencapai keselarasan:
Threading membolehkan anda menjalankan berbilang unit proses yang lebih kecil, dipanggil benang, dalam proses yang sama, berkongsi ruang memori yang sama.
Benang lebih ringan daripada proses dan bertukar antara mereka lebih cepat.
Walau bagaimanapun, threading dalam Python tertakluk kepada Global Interpreter Lock (GIL), yang memastikan hanya satu thread boleh melaksanakan kod Python pada satu masa.
Modul benang Python menyediakan cara yang mudah dan fleksibel untuk mencipta dan mengurus benang.
Mari kita mulakan dengan contoh asas:
import threading import time def print_numbers(): for i in range(5): print(f"Number: {i}") time.sleep(1) # Creating a thread thread = threading.Thread(target=print_numbers) # Starting the thread thread.start() # Wait for the thread to complete thread.join() print("Thread has finished executing") # Output: # Number: 0 # Number: 1 # Number: 2 # Number: 3 # Number: 4 # Thread has finished executing
Dalam contoh ini:
Threading amat berguna untuk tugas terikat I/O, seperti operasi fail, permintaan rangkaian atau pertanyaan pangkalan data, di mana program menghabiskan sebahagian besar masanya menunggu sumber luaran.
Berikut ialah contoh yang mensimulasikan muat turun fail menggunakan benang:
import threading import time def download_file(file_name): print(f"Starting download of {file_name}...") time.sleep(2) # Simulate download time print(f"Finished downloading {file_name}") files = ["file1.zip", "file2.zip", "file3.zip"] threads = [] # Create and start threads for file in files: thread = threading.Thread(target=download_file, args=(file,)) thread.start() threads.append(thread) # Ensure all threads have finished for thread in threads: thread.join() print("All files have been downloaded.") # Output: # Starting download of file1.zip... # Starting download of file2.zip... # Starting download of file3.zip... # Finished downloading file1.zip # Finished downloading file2.zip # Finished downloading file3.zip # All files have been downloaded.
Dengan mencipta dan mengurus urutan berasingan untuk setiap muat turun fail, program ini boleh mengendalikan berbilang tugas serentak, meningkatkan kecekapan keseluruhan.
Langkah utama dalam kod adalah seperti berikut:
Walaupun threading boleh meningkatkan prestasi untuk tugas terikat I/O, ia mempunyai had:
Pemprosesan berbilang menangani had penjalinan dengan menggunakan proses yang berasingan dan bukannya utas.
Setiap proses mempunyai ruang memori sendiri dan penterjemah Python, membenarkan keselarian sebenar pada sistem berbilang teras.
Ini menjadikan pemproses berbilang sesuai untuk tugasan yang memerlukan pengiraan yang berat.
Modul pemproses berbilang dalam Python membolehkan anda mencipta dan mengurus proses dengan mudah.
Let’s start with a basic example:
import multiprocessing import time def print_numbers(): for i in range(5): print(f"Number: {i}") time.sleep(1) if __name__ == "__main__": # Creating a process process = multiprocessing.Process(target=print_numbers) # Starting the process process.start() # Wait for the process to complete process.join() print("Process has finished executing") # Output: # Number: 0 # Number: 1 # Number: 2 # Number: 3 # Number: 4 # Process has finished executing
This example is similar to the threading example, but with processes.
Notice that the process creation and management are similar to threading, but because processes run in separate memory spaces, they are truly concurrent and can run on different CPU cores.
Multiprocessing is particularly beneficial for tasks that are CPU-bound, such as numerical computations or data processing.
Here’s an example that calculates the square of numbers using multiple processes:
import multiprocessing def compute_square(number): return number * number if __name__ == "__main__": numbers = [1, 2, 3, 4, 5] # Create a pool of processes with multiprocessing.Pool() as pool: # Map function to numbers using multiple processes results = pool.map(compute_square, numbers) print("Squares:", results) # Output: # Squares: [1, 4, 9, 16, 25]
Here are the key steps in the code:
Since each process has its own memory space, sharing data between processes requires inter-process communication (IPC) mechanisms.
The multiprocessing module provides several tools for IPC, such as Queue, Pipe, and Value.
Here’s an example using Queue to share data between processes:
import multiprocessing def worker(queue): # Retrieve and process data from the queue while not queue.empty(): item = queue.get() print(f"Processing {item}") if __name__ == "__main__": queue = multiprocessing.Queue() # Add items to the queue for i in range(10): queue.put(i) # Create a pool of processes to process the queue processes = [] for _ in range(4): process = multiprocessing.Process(target=worker, args=(queue,)) processes.append(process) process.start() # Wait for all processes to complete for process in processes: process.join() print("All processes have finished.") # Output: # Processing 0 # Processing 1 # Processing 2 # Processing 3 # Processing 4 # Processing 5 # Processing 6 # Processing 7 # Processing 8 # Processing 9 # All processes have finished.
In this example:
While multiprocessing provides true parallelism, it comes with its own set of challenges:
Choosing between threading and multiprocessing depends on the type of task you're dealing with:
Use Threading:
Use Multiprocessing:
Concurrency in Python is a powerful way to make your applications run faster.
Threading is great for tasks that involve a lot of waiting, like network operations or reading/writing files, but it's not as effective for tasks that require heavy computations because of something called the Global Interpreter Lock (GIL).
On the other hand, multiprocessing allows for true parallelism, making it perfect for CPU-intensive tasks, although it comes with higher overhead and complexity.
Sama ada anda sedang memproses data, mengendalikan berbilang permintaan rangkaian atau melakukan pengiraan yang rumit, alat penjalinan dan pemproses berbilang Python memberi anda perkara yang anda perlukan untuk menjadikan program anda secekap dan sepantas mungkin.
Atas ialah kandungan terperinci Concurrency dalam Python dengan Threading dan Multiprocessing. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!