Multithreading dengan Python dengan Contoh:Belajar GIL dengan Python
Bahasa pemrograman python memungkinkan Anda untuk menggunakan multiprocessing atau multithreading. Dalam tutorial ini, Anda akan belajar cara menulis aplikasi multithread dengan Python.
Apa itu Utas?
Utas adalah unit eksekusi pada pemrograman bersamaan. Multithreading adalah teknik yang memungkinkan CPU untuk mengeksekusi banyak tugas dari satu proses pada waktu yang sama. Utas ini dapat dijalankan satu per satu sambil membagikan sumber daya prosesnya.
Apa itu Proses?
Sebuah proses pada dasarnya adalah program yang sedang dieksekusi. Saat Anda memulai aplikasi di komputer Anda (seperti browser atau editor teks), sistem operasi membuat proses .
Apa itu Multithreading dengan Python?
Multithreading dengan Python pemrograman adalah teknik terkenal di mana banyak utas dalam suatu proses berbagi ruang data mereka dengan utas utama yang membuat berbagi informasi dan komunikasi dalam utas menjadi mudah dan efisien. Utas lebih ringan dari proses. Multi utas dapat dijalankan secara individual sambil berbagi sumber daya prosesnya. Tujuan dari multithreading adalah untuk menjalankan banyak tugas dan sel fungsi secara bersamaan.
Dalam tutorial ini, Anda akan belajar,
Apa itu Benang?
Apa itu Proses?
Apa itu Multithreading?
Apa itu Multiprosesor?
Python Multithreading vs Multiprocessing
Mengapa menggunakan Multithreading?
Python MultiThreading
Modul Thread dan Threading
Modul Utas
Modul Penyusunan
Deadlock dan kondisi Balapan
Menyinkronkan rangkaian pesan
Apa itu GIL?
Mengapa GIL dibutuhkan?
Apa itu Multiprosesing?
Multiprocessing memungkinkan Anda untuk menjalankan beberapa proses yang tidak terkait secara bersamaan. Proses ini tidak berbagi sumber daya dan berkomunikasi melalui IPC.
Python Multithreading vs Multiprocessing
Untuk memahami proses dan utas, pertimbangkan skenario ini:Berkas .exe di komputer Anda adalah sebuah program. Saat Anda membukanya, OS memuatnya ke dalam memori, dan CPU menjalankannya. Contoh program yang sedang berjalan disebut proses.
Setiap proses akan memiliki 2 komponen mendasar:
Kode
Data
Sekarang, sebuah proses dapat berisi satu atau lebih sub-bagian yang disebut utas. Ini tergantung pada arsitektur OS. Anda dapat menganggap thread sebagai bagian dari proses yang dapat dijalankan secara terpisah oleh sistem operasi.
Dengan kata lain, ini adalah aliran instruksi yang dapat dijalankan secara independen oleh OS. Utas dalam satu proses berbagi data dari proses tersebut dan dirancang untuk bekerja sama guna memfasilitasi paralelisme.
Mengapa menggunakan Multithreading?
Multithreading memungkinkan Anda untuk memecah aplikasi menjadi beberapa sub-tugas dan menjalankan tugas-tugas ini secara bersamaan. Jika Anda menggunakan multithreading dengan benar, kecepatan, kinerja, dan rendering aplikasi Anda dapat ditingkatkan.
Python MultiThreading
Python mendukung konstruksi untuk multiprocessing serta multithreading. Dalam tutorial ini, Anda terutama akan berfokus pada penerapan multithreaded aplikasi dengan python. Ada dua modul utama yang dapat digunakan untuk menangani thread dengan Python:
Utas modul, dan
Utasan modul
Namun, dalam python, ada juga sesuatu yang disebut kunci juru bahasa global (GIL). Itu tidak memungkinkan peningkatan kinerja yang besar dan bahkan dapat mengurangi kinerja beberapa aplikasi multithreaded. Anda akan mempelajari semuanya di bagian berikutnya dari tutorial ini.
Modul Thread dan Threading
Dua modul yang akan Anda pelajari dalam tutorial ini adalah modul thread dan modul threading .
Namun, modul utas sudah lama tidak digunakan lagi. Dimulai dengan Python 3, telah ditetapkan sebagai usang dan hanya dapat diakses sebagai __thread untuk kompatibilitas mundur.
Anda harus menggunakan utas tingkat yang lebih tinggi modul untuk aplikasi yang ingin Anda terapkan. Modul utas hanya dibahas di sini untuk tujuan pendidikan.
Modul Utas
Sintaks untuk membuat thread baru menggunakan modul ini adalah sebagai berikut:
thread.start_new_thread(function_name, arguments)
Baiklah, sekarang Anda telah membahas teori dasar untuk memulai coding. Jadi, buka IDLE atau notepad Anda dan ketik berikut ini:
import time
import _thread
def thread_test(name, wait):
i = 0
while i <= 3:
time.sleep(wait)
print("Running %s\n" %name)
i = i + 1
print("%s has finished execution" %name)
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))
Simpan file dan tekan F5 untuk menjalankan program. Jika semuanya dilakukan dengan benar, ini adalah output yang akan Anda lihat:
Anda akan mempelajari lebih lanjut tentang kondisi balapan dan cara menanganinya di bagian mendatang
KODE PENJELASAN
Pernyataan ini mengimpor modul waktu dan utas yang digunakan untuk menangani eksekusi dan penundaan utas Python.
Di sini, Anda telah mendefinisikan fungsi yang disebut thread_test, yang akan dipanggil oleh start_new_thread metode. Fungsi menjalankan loop sementara untuk empat iterasi dan mencetak nama utas yang memanggilnya. Setelah iterasi selesai, ia mencetak pesan yang mengatakan bahwa utas telah selesai dieksekusi.
Ini adalah bagian utama dari program Anda. Di sini, Anda cukup memanggil start_new_thread metode dengan thread_test berfungsi sebagai argumen. Ini akan membuat utas baru untuk fungsi yang Anda berikan sebagai argumen dan mulai menjalankannya. Perhatikan bahwa Anda dapat mengganti ini (utas_ test) dengan fungsi lain yang ingin Anda jalankan sebagai utas.
Modul Ulir
Modul ini adalah implementasi tingkat tinggi dari threading di python dan standar de facto untuk mengelola aplikasi multithreaded. Ini menyediakan berbagai fitur jika dibandingkan dengan modul thread.
Berikut adalah daftar beberapa fungsi berguna yang didefinisikan dalam modul ini:
Nama Fungsi
Deskripsi
activeCount()
Mengembalikan jumlah Utas benda yang masih hidup
currentThread()
Mengembalikan objek kelas Thread saat ini.
menghitung()
Mencantumkan semua objek Thread yang aktif.
isDaemon()
Mengembalikan nilai true jika utasnya adalah daemon.
isAlive()
Mengembalikan nilai true jika utasnya masih hidup.
Metode Kelas Utas
mulai()
Memulai aktivitas thread. Itu harus dipanggil hanya sekali untuk setiap utas karena akan menimbulkan kesalahan runtime jika dipanggil beberapa kali.
lari()
Metode ini menunjukkan aktivitas thread dan dapat ditimpa oleh kelas yang memperluas kelas Thread.
bergabung()
Ini memblokir eksekusi kode lain hingga utas di mana metode join() dipanggil dihentikan.
Latar Belakang:Kelas Thread
Sebelum Anda mulai coding program multithreaded menggunakan modul threading, penting untuk memahami tentang kelas Thread. Kelas thread adalah kelas utama yang mendefinisikan template dan operasi thread di python.
Cara paling umum untuk membuat aplikasi python multithread adalah dengan mendeklarasikan kelas yang memperluas kelas Thread dan mengganti metode run()-nya.
Kelas Thread, secara ringkas, menandakan urutan kode yang berjalan di utas separate yang terpisah kendali.
Jadi, saat menulis aplikasi multithread, Anda akan melakukan hal berikut:
mendefinisikan kelas yang memperluas kelas Thread
Ganti __init__ konstruktor
Mengganti run() metode
Setelah objek utas dibuat, start() metode dapat digunakan untuk memulai eksekusi aktivitas ini dan join() metode dapat digunakan untuk memblokir semua kode lain hingga aktivitas saat ini selesai.
Sekarang, mari kita coba menggunakan modul threading untuk mengimplementasikan contoh sebelumnya. Sekali lagi, jalankan IDLE Anda dan ketik berikut ini:
import time
import threading
class threadtester (threading.Thread):
def __init__(self, id, name, i):
threading.Thread.__init__(self)
self.id = id
self.name = name
self.i = i
def run(self):
thread_test(self.name, self.i, 5)
print ("%s has finished execution " %self.name)
def thread_test(name, wait, i):
while i:
time.sleep(wait)
print ("Running %s \n" %name)
i = i - 1
if __name__=="__main__":
thread1 = threadtester(1, "First Thread", 1)
thread2 = threadtester(2, "Second Thread", 2)
thread3 = threadtester(3, "Third Thread", 3)
thread1.start()
thread2.start()
thread3.start()
thread1.join()
thread2.join()
thread3.join()
Ini akan menjadi output ketika Anda menjalankan kode di atas:
KODE PENJELASAN
Bagian ini sama dengan contoh kita sebelumnya. Di sini, Anda mengimpor modul waktu dan utas yang digunakan untuk menangani eksekusi dan penundaan utas Python.
Dalam bit ini, Anda membuat kelas yang disebut threadtester, yang mewarisi atau memperluas Thread kelas modul threading. Ini adalah salah satu cara paling umum untuk membuat utas dengan python. Namun, Anda hanya boleh mengganti konstruktor dan run() metode di aplikasi Anda. Seperti yang Anda lihat pada contoh kode di atas, __init__ metode (konstruktor) telah diganti. Demikian pula, Anda juga telah mengganti run() metode. Ini berisi kode yang ingin Anda jalankan di dalam utas. Dalam contoh ini, Anda telah memanggil fungsi thread_test().
Ini adalah metode thread_test() yang mengambil nilai i sebagai argumen, kurangi 1 pada setiap iterasi dan perulangan melalui sisa kode hingga i menjadi 0. Dalam setiap iterasi, ia mencetak nama utas yang sedang dieksekusi dan tidur selama beberapa detik (yang juga dianggap sebagai argumen ).
thread1 =threadtester(1, “First Thread”, 1) Di sini, kita membuat thread dan meneruskan tiga parameter yang kita deklarasikan di __init__. Parameter pertama adalah id utas, parameter kedua adalah nama utas, dan parameter ketiga adalah penghitung, yang menentukan berapa kali perulangan while harus dijalankan.
thread2.start()T metode start digunakan untuk memulai eksekusi sebuah thread. Secara internal, fungsi start() memanggil metode run() kelas Anda.
thread3.join() Metode join() memblokir eksekusi kode lain dan menunggu hingga thread yang dipanggil selesai.
Seperti yang sudah Anda ketahui, utas yang berada dalam proses yang sama memiliki akses ke memori dan data dari proses itu. Akibatnya, jika lebih dari satu utas mencoba mengubah atau mengakses data secara bersamaan, kesalahan mungkin muncul.
Di bagian berikutnya, Anda akan melihat berbagai jenis komplikasi yang dapat muncul saat thread mengakses data dan critical-section tanpa memeriksa transaksi akses yang ada.
Deadlock dan kondisi Balapan
Sebelum mempelajari tentang deadlock dan kondisi balapan, akan sangat membantu untuk memahami beberapa definisi dasar yang terkait dengan pemrograman bersamaan:
Bagian KritisIni adalah fragmen kode yang mengakses atau memodifikasi variabel bersama dan harus dilakukan sebagai transaksi atomik.
Context SwitchIni adalah proses yang diikuti CPU untuk menyimpan status thread sebelum berpindah dari satu tugas ke tugas lainnya sehingga dapat dilanjutkan dari titik yang sama nanti.
Deadlock
Kebuntuan adalah masalah yang paling ditakuti yang dihadapi pengembang saat menulis aplikasi bersamaan/multithreaded dengan python. Cara terbaik untuk memahami kebuntuan adalah dengan menggunakan contoh masalah ilmu komputer klasik yang dikenal sebagai Masalah Filsuf Makan.
Rumusan masalah untuk filosof makan adalah sebagai berikut:
Lima filsuf duduk di meja bundar dengan lima piring spageti (sejenis pasta) dan lima garpu, seperti yang ditunjukkan pada diagram.