Python 3 - Pemrograman Multithreaded
Menjalankan beberapa utas mirip dengan menjalankan beberapa program berbeda secara bersamaan, tetapi dengan manfaat berikut -
Beberapa utas dalam proses berbagi ruang data yang sama dengan utas utama dan oleh karena itu dapat berbagi informasi atau berkomunikasi satu sama lain dengan lebih mudah daripada jika mereka adalah proses terpisah.
Benang kadang-kadang disebut proses ringan dan tidak membutuhkan banyak memori tambahan; mereka lebih murah daripada proses.
Sebuah utas memiliki awal, urutan eksekusi, dan kesimpulan. Ini memiliki penunjuk instruksi yang melacak di mana dalam konteksnya saat ini berjalan.
Itu bisa dicegah (terputus).
Ini sementara dapat ditahan (juga dikenal sebagai tidur) sementara utas lain sedang berjalan - ini disebut menyerah.
Ada dua jenis utas -
- benang kernel
- utas pengguna
Kernel Threads adalah bagian dari sistem operasi, sedangkan utas ruang pengguna tidak diterapkan di kernel.
Ada dua modul yang mendukung penggunaan utas di Python3 -
- _thread
- threading
Modul utas sudah "tidak digunakan lagi" untuk waktu yang cukup lama. Pengguna didorong untuk menggunakan modul threading sebagai gantinya. Karenanya, di Python 3, modul "utas" tidak tersedia lagi. Namun, telah diubah namanya menjadi "_thread" untuk kompatibilitas dengan Python3.
Memulai Thread Baru
Untuk menelurkan utas lain, Anda perlu memanggil metode berikut yang tersedia di modul utas -
_thread.start_new_thread ( function, args[, kwargs] )
Panggilan metode ini memungkinkan cara yang cepat dan efisien untuk membuat utas baru di Linux dan Windows.
Pemanggilan metode segera kembali dan utas anak dimulai dan memanggil fungsi dengan daftar args yang diteruskan . Saat fungsi kembali, utas berakhir.
Di sini, args adalah tuple argumen; gunakan tupel kosong untuk memanggil fungsi tanpa memberikan argumen apa pun. kwargs adalah kamus opsional dari argumen kata kunci.
Contoh
#!/usr/bin/python3
import _thread
import time
# Define a function for the thread
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print ("%s: %s" % ( threadName, time.ctime(time.time()) ))
# Create two threads as follows
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
Keluaran
Ketika kode di atas dijalankan, itu menghasilkan hasil sebagai berikut -
Thread-1: Fri Feb 19 09:41:39 2016
Thread-2: Fri Feb 19 09:41:41 2016
Thread-1: Fri Feb 19 09:41:41 2016
Thread-1: Fri Feb 19 09:41:43 2016
Thread-2: Fri Feb 19 09:41:45 2016
Thread-1: Fri Feb 19 09:41:45 2016
Thread-1: Fri Feb 19 09:41:47 2016
Thread-2: Fri Feb 19 09:41:49 2016
Thread-2: Fri Feb 19 09:41:53 2016
Program berjalan dalam putaran tak terbatas. Anda harus menekan ctrl-c untuk berhenti
Meskipun sangat efektif untuk penguliran tingkat rendah, modul ulir sangat terbatas dibandingkan dengan modul penguliran yang lebih baru.
Modul Penguliran
Modul threading yang lebih baru yang disertakan dengan Python 2.4 memberikan dukungan tingkat tinggi yang jauh lebih kuat untuk utas daripada modul utas yang dibahas di bagian sebelumnya.
The threading modul mengekspos semua metode dari benang modul dan menyediakan beberapa metode tambahan -
threading.activeCount() - Mengembalikan jumlah objek utas yang aktif.
threading.currentThread() - Mengembalikan jumlah objek utas dalam kontrol utas pemanggil.
threading.enumerate() - Menampilkan daftar semua objek utas yang saat ini aktif.
Selain metodenya, modul threading memiliki kelas Thread yang mengimplementasikan threading. Metode yang disediakan oleh kelas Thread adalah sebagai berikut -
run() - Metode run () adalah titik masuk untuk utas.
start() - Metode start () memulai utas dengan memanggil metode run.
join([time]) - Join () menunggu utas berakhir.
isAlive() - Metode isAlive () memeriksa apakah utas masih dijalankan.
getName() - Metode getName () mengembalikan nama utas.
setName() - Metode setName () menetapkan nama utas.
Membuat Thread Menggunakan Modul Threading
Untuk mengimplementasikan utas baru menggunakan modul threading, Anda harus melakukan hal berikut -
Tentukan subclass baru dari kelas Thread .
Ganti metode __init __ (self [, args]) untuk menambahkan argumen tambahan.
Kemudian, ganti metode run (self [, args]) untuk mengimplementasikan apa yang harus dilakukan thread saat dimulai.
Setelah Anda membuat subkelas Thread baru , Anda dapat membuat instance-nya dan kemudian memulai thread baru dengan menjalankan start () , yang pada gilirannya akan memanggil metode run () .
Contoh
#!/usr/bin/python3
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, self.counter, 5)
print ("Exiting " + self.name)
def print_time(threadName, delay, counter):
while counter:
if exitFlag:
threadName.exit()
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1
# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print ("Exiting Main Thread")
Hasil
Ketika kami menjalankan program di atas, ini menghasilkan hasil sebagai berikut -
Starting Thread-1
Starting Thread-2
Thread-1: Fri Feb 19 10:00:21 2016
Thread-2: Fri Feb 19 10:00:22 2016
Thread-1: Fri Feb 19 10:00:22 2016
Thread-1: Fri Feb 19 10:00:23 2016
Thread-2: Fri Feb 19 10:00:24 2016
Thread-1: Fri Feb 19 10:00:24 2016
Thread-1: Fri Feb 19 10:00:25 2016
Exiting Thread-1
Thread-2: Fri Feb 19 10:00:26 2016
Thread-2: Fri Feb 19 10:00:28 2016
Thread-2: Fri Feb 19 10:00:30 2016
Exiting Thread-2
Exiting Main Thread
Sinkronisasi Thread
Modul threading yang disediakan oleh Python menyertakan mekanisme penguncian yang mudah diterapkan yang memungkinkan Anda untuk menyinkronkan utas. Kunci baru dibuat dengan memanggil metode Lock () , yang mengembalikan kunci baru.
Metode perolehan (pemblokiran) dari objek kunci baru digunakan untuk memaksa utas berjalan secara sinkron. Parameter pemblokiran opsional memungkinkan Anda untuk mengontrol apakah utas menunggu untuk mendapatkan kunci.
Jika pemblokiran diatur ke 0, utas segera kembali dengan nilai 0 jika kunci tidak dapat diperoleh dan dengan 1 jika kunci diperoleh. Jika pemblokiran diatur ke 1, utas akan memblokir dan menunggu kunci dilepaskan.
Metode release () dari objek kunci baru digunakan untuk melepaskan kunci saat tidak lagi diperlukan.
Contoh
#!/usr/bin/python3
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)
# Get lock to synchronize threads
threadLock.acquire()
print_time(self.name, self.counter, 3)
# Free lock to release next thread
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 = []
# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
# Add threads to thread list
threads.append(thread1)
threads.append(thread2)
# Wait for all threads to complete
for t in threads:
t.join()
print ("Exiting Main Thread")
Keluaran
Ketika kode di atas dijalankan, itu menghasilkan hasil sebagai berikut -
Starting Thread-1
Starting Thread-2
Thread-1: Fri Feb 19 10:04:14 2016
Thread-1: Fri Feb 19 10:04:15 2016
Thread-1: Fri Feb 19 10:04:16 2016
Thread-2: Fri Feb 19 10:04:18 2016
Thread-2: Fri Feb 19 10:04:20 2016
Thread-2: Fri Feb 19 10:04:22 2016
Exiting Main Thread
Antrean Prioritas Multithread
The Antrian modul memungkinkan Anda untuk membuat objek antrian baru yang dapat menampung jumlah tertentu item. Ada metode berikut untuk mengontrol Antrian -
get() - Get () menghapus dan mengembalikan item dari antrian.
put() - Put menambahkan item ke antrian.
qsize() - The qsize () mengembalikan jumlah item yang saat ini berada dalam antrian.
empty()- empty () mengembalikan True jika antrian kosong; jika tidak, Salah.
full()- full () mengembalikan True jika antrian penuh; jika tidak, Salah.
Contoh
#!/usr/bin/python3
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
# Create new threads
for tName in threadList:
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# Fill the queue
queueLock.acquire()
for word in nameList:
workQueue.put(word)
queueLock.release()
# Wait for queue to empty
while not workQueue.empty():
pass
# Notify threads it's time to exit
exitFlag = 1
# Wait for all threads to complete
for t in threads:
t.join()
print ("Exiting Main Thread")
Keluaran
Ketika kode di atas dijalankan, itu menghasilkan hasil 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