Pemrograman Multithread Python: Teknik Konkesi Efisien
Halaman Sebelumnya Halaman Berikutnya
Menjalankan beberapa thread mirip dengan menjalankan beberapa program yang berbeda secara bersamaan, dengan manfaat berikut −
Beberapa thread dalam suatu proses berbagi ruang data yang sama dengan thread utama dan dapat dengan mudah berbagi informasi atau berkomunikasi satu sama lain dibandingkan jika mereka adalah proses terpisah.
Thread terkadang disebut proses ringan dan tidak memerlukan banyak overhead memori; mereka lebih murah daripada proses.
Sebuah thread memiliki awal, urutan eksekusi, dan kesimpulan. Ia memiliki penunjuk instruksi yang melacak di mana dalam konteksnya ia saat ini berjalan.
Memulai Thread Baru
Untuk membuat thread lain, Anda perlu memanggil metode berikut yang tersedia dalam modul thread −
thread.start_new_thread ( function, args[, kwargs] )
Panggilan metode ini memungkinkan cara yang cepat dan efisien untuk membuat thread baru baik di Linux maupun Windows.
Panggilan metode ini segera kembali dan thread anak dimulai dan memanggil fungsi dengan daftar args yang diteruskan. Saat fungsi kembali, thread diakhiri.
Di sini, args adalah tuple argumen; gunakan tuple kosong untuk memanggil fungsi tanpa melewatkan argumen apa pun. kwargs adalah kamus opsional dari argumen kata kunci.
Contoh
#!/usr/bin/python import thread import time # Definisikan fungsi untuk thread def print_time( threadName, delay): count = 0 while count < 5: time.sleep(delay) count += 1 print "%s: %s" % ( threadName, time.ctime(time.time()) ) # Buat dua thread sebagai berikut try: thread.start_new_thread( print_time, ("Thread-1", 2, ) ) thread.start_new_thread( print_time, ("Thread-2", 4, ) ) except: print "Error: unable to start thread" while 1: pass Saat kode di atas dieksekusi, hasilnya adalah sebagai berikut −
Thread-1: Thu Jan 22 15:42:17 2009 Thread-1: Thu Jan 22 15:42:19 2009 Thread-2: Thu Jan 22 15:42:19 2009 Thread-1: Thu Jan 22 15:42:21 2009 Thread-2: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:25 2009 Thread-2: Thu Jan 22 15:42:27 2009 Thread-2: Thu Jan 22 15:42:31 2009 Thread-2: Thu Jan 22 15:42:35 2009
Meskipun ini sangat efektif untuk threading tingkat rendah, modul thread sangat terbatas dibandingkan dengan modul threading yang lebih baru.
Modul Threading
Modul threading yang lebih baru yang disertakan dengan Python 2.4 menyediakan dukungan tingkat tinggi yang jauh lebih kuat untuk thread dibandingkan dengan modul thread yang dibahas di bagian sebelumnya.
Modul threading mengekspos semua metode dari modul thread dan menyediakan beberapa metode tambahan −
threading.activeCount() − Mengembalikan jumlah objek thread yang aktif.
threading.currentThread() − Mengembalikan jumlah objek thread dalam kontrol thread pemanggil.
threading.enumerate() − Mengembalikan daftar semua objek thread yang saat ini aktif.
Selain metode, modul threading memiliki kelas Thread yang mengimplementasikan threading. Metode yang disediakan oleh kelas Thread adalah sebagai berikut −
run() − Metode run() adalah titik entri untuk thread.
start() − Metode start() memulai thread dengan memanggil metode run.
join([time]) − Metode join() menunggu thread untuk diakhiri.
isAlive() − Metode isAlive() memeriksa apakah thread masih sedang dieksekusi.
getName() − Metode getName() mengembalikan nama thread.
setName() − Metode setName() mengatur nama thread.
Membuat Thread Menggunakan Modul Threading
Untuk mengimplementasikan thread baru menggunakan modul threading, Anda harus melakukan hal berikut −
Definisikan subclass baru dari kelas Thread.
Imbau metode __init__(self [,args]) untuk menambahkan argumen tambahan.
Kemudian, imbau metode run(self [,args]) untuk mengimplementasikan apa yang harus dilakukan thread saat dimulai.
Setelah Anda membuat subclass Thread baru, Anda dapat membuat instance dari itu dan kemudian memulai thread baru dengan memanggil start(), yang kemudian memanggil metode run().
Contoh
#!/usr/bin/python import threading import time exitFlag = 0 class myThread (threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): print "Starting " + self.name print_time(self.name, 5, self.counter) print "Exiting " + self.name def print_time(threadName, counter, delay): while counter: if exitFlag: threadName.exit() time.sleep(delay) print "%s: %s" % (threadName, time.ctime(time.time())) counter -= 1 # Buat thread baru thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # Mulai thread baru thread1.start() thread2.start() print "Exiting Main Thread"
Saat kode di atas dieksekusi, hasilnya adalah sebagai berikut −
Starting Thread-1 Starting Thread-2 Exiting Main Thread Thread-1: Thu Mar 21 09:10:03 2013 Thread-1: Thu Mar 21 09:10:04 2013 Thread-2: Thu Mar 21 09:10:04 2013 Thread-1: Thu Mar 21 09:10:05 2013 Thread-1: Thu Mar 21 09:10:06 2013 Thread-2: Thu Mar 21 09:10:06 2013 Thread-1: Thu Mar 21 09:10:07 2013 Exiting Thread-1 Thread-2: Thu Mar 21 09:10:08 2013 Thread-2: Thu Mar 21 09:10:10 2013 Thread-2: Thu Mar 21 09:10:12 2013 Exiting Thread-2
Sinkronisasi Thread
Modul threading yang disediakan dengan Python menyediakan mekanisme kunci yang mudah diimplementasikan yang memungkinkan Anda untuk mensinkronkan thread. Kunci baru dibuat dengan memanggil metode Lock(), yang mengembalikan kunci baru.
Metode acquire(blocking) dari objek kunci baru digunakan untuk memaksa thread berjalan secara sinkron. Parameter opsional blocking memungkinkan Anda untuk mengontrol apakah thread menunggu untuk mendapatkan kunci.
Jika blocking diatur ke 0, thread segera kembali dengan nilai 0 jika kunci tidak dapat diperoleh dan dengan 1 jika kunci diperoleh. Jika blocking diatur ke 1, thread akan memblokir dan menunggu kunci dilepaskan.
Metode release() dari objek kunci baru digunakan untuk melepaskan kunci ketika tidak lagi diperlukan.
Contoh
#!/usr/bin/python import threading import time class myThread (threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): print "Starting " + self.name # Dapatkan kunci untuk mensinkronkan thread threadLock.acquire() print_time(self.name, self.counter, 3) # Lepas kunci untuk melepaskan thread berikutnya threadLock.release() def print_time(threadName, delay, counter): while counter: time.sleep(delay) print "%s: %s" % (threadName, time.ctime(time.time())) counter -= 1 threadLock = threading.Lock() threads = [] # Buat thread baru thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # Mulai thread baru thread1.start() thread2.start() # Tambahkan thread ke daftar thread threads.append(thread1) threads.append(thread2) # Tunggu semua thread selesai for t in threads: t.join() print "Exiting Main Thread"
Saat kode di atas dieksekusi, hasilnya adalah sebagai berikut −
Starting Thread-1 Starting Thread-2 Thread-1: Thu Mar 21 09:11:28 2013 Thread-1: Thu Mar 21 09:11:29 2013 Thread-1: Thu Mar 21 09:11:30 2013 Thread-2: Thu Mar 21 09:11:32 2013 Thread-2: Thu Mar 21 09:11:34 2013 Thread-2: Thu Mar 21 09:11:36 2013 Exiting Main Thread
Antrian Prioritas Multithread
Modul Queue memungkinkan Anda untuk membuat objek antrian baru yang dapat menampung sejumlah item tertentu. Ada beberapa metode untuk mengontrol Antrian −
get() − Metode get() menghapus dan mengembalikan item dari antrian.
put() − Metode put menambahkan item ke antrian.
qsize() − Metode qsize() mengembalikan jumlah item yang saat ini ada dalam antrian.
empty() − Metode empty( ) mengembalikan True jika antrian kosong; jika tidak, False.
full() − Metode full() mengembalikan True jika antrian penuh; jika tidak, False.
Contoh
#!/usr/bin/python import Queue import threading import time exitFlag = 0 class myThread (threading.Thread): def __init__(self, threadID, name, q): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.q = q def run(self): print "Starting " + self.name process_data(self.name, self.q) print "Exiting " + self.name def process_data(threadName, q): while not exitFlag: queueLock.acquire() if not workQueue.empty(): data = q.get() queueLock.release() print "%s processing %s" % (threadName, data) else: queueLock.release() time.sleep(1) threadList = ["Thread-1", "Thread-2", "Thread-3"] nameList = ["One", "Two", "Three", "Four", "Five"] queueLock = threading.Lock() workQueue = Queue.Queue(10) threads = [] threadID = 1 # Buat thread baru for tName in threadList: thread = myThread(threadID, tName, workQueue) thread.start() threads.append(thread) threadID += 1 # Isi antrian queueLock.acquire() for word in nameList: workQueue.put(word) queueLock.release() # Tunggu antrian kosong while not workQueue.empty(): pass # Beritahu thread saatnya untuk keluar exitFlag = 1 # Tunggu semua thread selesai for t in threads: t.join() print "Exiting Main Thread"
Saat kode di atas dieksekusi, hasilnya adalah sebagai berikut −
Starting Thread-1 Starting Thread-2 Starting Thread-3 Thread-1 processing One Thread-2 processing Two Thread-3 processing Three Thread-1 processing Four Thread-2 processing Five Exiting Thread-3 Exiting Thread-1 Exiting Thread-2 Exiting Main Thread