Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Industrial programming >> Python

Menguasai Multithreading Python: GIL Dijelaskan dengan Contoh Praktis

Python menawarkan baik multiprocessing maupun multithreading untuk mempercepat beban kerja. Panduan ini memandu Anda melalui pembuatan aplikasi berbasis thread yang kuat, nuansa Global Interpreter Lock (GIL), dan cara menghindari jebakan umum seperti deadlock dan race condition.

Apa itu Thread?

Thread adalah unit eksekusi ringan dalam satu proses. Thread berbagi ruang memori proses, memungkinkan pertukaran data yang efisien, sementara sistem operasi menjadwalkan mereka untuk berjalan secara bersamaan pada satu atau lebih inti CPU.

Apa itu Proses?

Proses adalah instance program yang independen. Saat Anda meluncurkan aplikasi—katakanlah peramban atau editor teks—OS membuat proses terpisah dengan kode, data, dan peta memori sendiri.

Dasar-Dasar Multithreading Python

Modul threading Python menyediakan API tingkat tinggi untuk mengelola thread, sedangkan modul legacy _thread sudah usang dan hanya dipertahankan untuk kompatibilitas mundur. Thread ideal untuk tugas I/O-bound, sementara tugas CPU-bound harus menggunakan modul multiprocessing untuk melewati GIL.

Kapan Menggunakan Multithreading

Multithreading unggul saat Anda perlu melakukan beberapa operasi I/O-beban—permintaan jaringan, I/O berkas, atau panggilan basis data—secara bersamaan. Thread yang dirancang dengan baik dapat meningkatkan responsivitas dan throughput tanpa overhead pembuatan proses baru.

Modul Python Utama untuk Threading

  1. _thread – Tingkat rendah, usang.
  2. threading – Modern, kaya fitur, dan pilihan yang direkomendasikan.

Menggunakan Modul threading

Modul threading menawarkan kelas Thread, primitif sinkronisasi (Lock, RLock, Semaphore, Condition, Event, Barrier), dan fungsi utilitas seperti activeCount() dan enumerate(). Di bawah ini adalah contoh minimal yang mendemonstrasikan pembuatan dan sinkronisasi thread.

import time import _thread def thread_test(name, wait): for i in range(4): time.sleep(wait) print(f"Running {name}") print(f"{name} has finished execution") if __name__ == "__main__": _thread.start_new_thread(thread_test, ("First Thread", 1)) _thread.start_new_thread(thread_test, ("Second Thread", 2)) _thread.start_new_thread(thread_test, ("Third Thread", 3)) 

Menjalankan kode ini menghasilkan output yang berselisih yang mendemonstrasikan eksekusi bersamaan.

Menguasai Multithreading Python: GIL Dijelaskan dengan Contoh Praktis

Penjelasan

  1. Impor time dan modul legacy _thread.
  2. Definisikan thread_test untuk melakukan tugas dan mencatat progresnya.
  3. Luncurkan tiga thread independen melalui start_new_thread.

Threading Modern dengan threading.Thread

Dalam praktiknya, Anda akan subclass threading.Thread dan menimpa metode run() miliknya. Contoh berikut mencermiliki perilaku sebelumnya tetapi menggunakan API tingkat tinggi.

import time import threading class ThreadTester(threading.Thread): def __init__(self, name, delay): super().__init__() self.name = name self.delay = delay def run(self): for _ in range(4): time.sleep(self.delay) print(f"Running {self.name}") print(f"{self.name} has finished execution") if __name__ == "__main__": threads = [ ThreadTester("First Thread", 1), ThreadTester("Second Thread", 2), ThreadTester("Third Thread", 3), ] for t in threads: t.start() for t in threads: t.join() 

Output:

Menguasai Multithreading Python: GIL Dijelaskan dengan Contoh Praktis

Penjelasan

  1. Subclass Thread untuk mengenkapsulasi perilaku thread.
  2. Timpa __init__ untuk menyimpan data spesifik thread.
  3. Timpa run untuk menentukan tugas.
  4. Buat instance, mulai, dan gabungkan setiap thread.

Jebakan Umum Threading

Deadlock

Deadlock terjadi ketika dua atau lebih thread menunggu tanpa batas untuk sumber daya yang dipegang oleh satu sama lain. Ilustrasi klasik: masalah Parafilosof Makan—lima filosofa berlomba untuk lima garpu, masing-masing membutuhkan dua garpu untuk makan. Jika setiap filosofa mengambil garpu kanan terlebih dahulu, siklus tunggu circular timbul, menghentikan semua progres.

Race Condition

Ketika beberapa thread memodifikasi data bersama tanpa koordinasi yang tepat, keadaan akhir dapat tidak dapat diprediksi. Misalnya:

i = 0 for _ in range(100): print(i) i += 1 

Meluncurkan loop ini dalam thread paralel dapat menghasilkan urutan yang acak karena peningkatan tumpang tindih.

Menyinkronkan Thread

Modul threading menyediakan beberapa primitif sinkronisasi. Yang paling dasar adalah Lock, yang memastikan akses eksklusif ke sumber daya bersama.

import threading lock = threading.Lock() def worker(name): for _ in range(5): lock.acquire() print(f"{name} acquired lock") # critical section lock.release() if __name__ == "__main__": t1 = threading.Thread(target=worker, args=("Thread A",)) t2 = threading.Thread(target=worker, args=("Thread B",)) t1.start(); t2.start() t1.join(); t2.join() 

Output menunjukkan akses yang diserialkan ke bagian kritis.

Menguasai Multithreading Python: GIL Dijelaskan dengan Contoh Praktis

Alat Sinkronisasi Lainnya

Memahami Global Interpreter Lock (GIL)

CPython menggunakan GIL untuk menyederhanakan eksekusi bytecode di seluruh thread. Sementara ini melindungi struktur internal interpreter (misalnya, perhitungan referensi) dari race condition, ini juga membatasi paralelisme untuk tugas CPU-bound pada sistem multi-core.

  1. Saat thread dimulai, ia memperoleh GIL.
  2. Jika thread lain membutuhkan GIL, ia menunggu hingga thread pertama melepaskannya.
  3. Thread I/O-bound melepaskan GIL selama pemblokiran panggilan, memungkinkan thread lain untuk berjalan.
  4. Thread CPU-bound memegang GIL, mencegah thread lain mengeksekusi kode Python.

Akibatnya, multithreading di Python menghasilkan sedikit manfaat untuk beban kerja komputasi intensif; multiprocessing adalah pendekatan yang disukai dalam kasus tersebut.

Mengapa GIL Ada

Pengumpul sampah CPython bergantung pada perhitungan referensi. Tanpa kunci global, pembaruan serentak pada hitungan referensi akan menyebabkan race condition dan kerusakan memori. Kunci per-objek akan memperkenalkan overhead yang signifikan, jadi GIL diadopsi sebagai solusi sederhana dan efektif.

Kesimpulan Praktis

Python

  1. Menguasai Fungsi free() dalam C: Panduan Praktis & Contoh
  2. Menguasai Metode strip() Python: Panduan Lengkap & Contoh Praktis
  3. Menguasai str.count() Python: Cara Menghitung Karakter & Substring dengan Contoh
  4. Fungsi round() Python Dijelaskan dengan Contoh Praktis
  5. Menguasai Fungsi map() Python: Sintaks, Contoh, dan Praktik Terbaik
  6. Python timeit() – Mengukur Waktu Eksekusi dengan Contoh Praktis
  7. Python Counter di collections – Perhitungan, Pembaruan, dan Operasi Aritmetika
  8. Python list.count(): Panduan Ahli dengan Contoh Praktis
  9. Python List index() – Cara Mencari Posisi Elemen dengan Contoh Praktis
  10. Menguasai Multithreading C#: Tingkatkan Performa dan Efisiensi