เธรด (Thread) ในวิทยาการคอมพิวเตอร์คือชุดคำสั่งที่สามารถจัดการได้อย่างอิสระโดย scheduler ซึ่งเป็นส่วนหนึ่งของระบบปฏิบัติการ
หน้าที่หลักของ Threading คือการรันหลายเธรดพร้อมกัน เธรดหมายถึงงานต่างๆ เรียกฟังก์ชันในโปรแกรม และหลายเธรดรันพร้อมกันไม่ได้หมายความว่ารันบนเครื่องต่างกัน
Multi-threading ใช้ใน 2 กรณีหลัก:
- เมื่อผลลัพธ์ของโปรแกรมย่อยต้องรวมกับโปรแกรมหลัก
- เมื่อโปรแกรมหลักมีส่วนของโค้ดที่อิสระต่อกันค่อนข้างมาก
โมดูล Threading
Python มีโมดูล threading ที่ทรงพลังและให้การสนับสนุนระดับสูงสำหรับเธรด
ฟังก์ชันสำคัญใน threading
| ฟังก์ชัน | คำอธิบาย |
|---|---|
threading.active_count() | คืนจำนวน Thread objects ที่ยังมีชีวิตอยู่ |
threading.current_thread() | คืน Thread object ปัจจุบันที่สอดคล้องกับ caller's thread of control |
threading.get_ident() | คืน 'thread identifier' ของเธรดปัจจุบัน (จำนวนเต็มไม่เป็นศูนย์) |
threading.enumerate() | คืนลิสต์ของ Thread objects ทั้งหมดที่ยังมีชีวิตอยู่ รวม daemon threads |
threading.main_thread() | คืน Main Thread object |
threading.settrace(func) | ตั้งค่า trace function สำหรับทุกเธรดที่เริ่มจาก threading module |
threading.setprofile(func) | ตั้งค่า profile function สำหรับทุกเธรด |
threading.stack_size([size]) | คืน/ตั้งค่า ขนาดสแต็กของเธรด ใช้ตอนสร้างเธรดใหม่ |
threading.TIMEOUT_MAX | ค่าคงที่สูงสุดสำหรับ timeout parameter ของ blocking functions |
โค้ดตัวอย่าง
import threading
def trace_function():
print("Passing the trace function")
def profile():
print("PROFILE THREAD: " + str(threading.current_thread().getName()))
class MyThread(threading.Thread):
def __init__(self, thread_name, thread_ID):
threading.Thread.__init__(self)
self.thread_name = thread_name
self.thread_ID = thread_ID
def run(self):
print(str(self.thread_ID))
print("ACTIVE THREADS ARE: " + str(threading.active_count()))
print("CURRENT THREAD IS: " + str(threading.current_thread().getName()))
# สร้างเธรด
my_thread1 = MyThread("PP", 500)
my_thread2 = MyThread("PythonProgram", 1000)
print("NAME OF THE MAIN THREAD: " + str(threading.main_thread().getName()))
print("IDENTIFICATION OF MAIN THREAD: " + str(threading.get_ident()))
print("STACK SIZE = " + str(threading.stack_size()))
threading.settrace(trace_function())
threading.setprofile(profile())
my_thread1.start()
my_thread2.start()
print("LIST OF ENUMERATION:")
print(threading.enumerate())
print("EXIT")
ผลลัพธ์ตัวอย่าง
NAME OF THE MAIN THREAD: MainThread
IDENTIFICATION OF MAIN THREAD: 5436
STACK SIZE = 0
Passing the trace function
None
PROFILE THREAD: MainThread
500
1000
LIST OF ENUMERATION:
ACTIVE THREADS ARE: 6
[<_MainThread(MainThread, started 5436)>, , ...]
EXIT
CURRENT THREAD IS: Thread-8
ACTIVE THREADS ARE: 5
CURRENT THREAD IS: Thread-9
ข้อสังเกต: Python มี GIL (Global Interpreter Lock) ทำให้ multithanning เหมาะกับ I/O-bound tasks ไม่ใช่ CPU-bound tasks สำหรับ CPU-bound ควรใช้ multiprocessing แทน