Thread là một đơn vị thực thi nhỏ nhất trong một tiến trình (process). Mỗi tiến trình có thể chứa nhiều thread, và các thread này có thể chạy song song, chia sẻ tài nguyên của tiến trình. Sử dụng thread giúp tăng hiệu suất của chương trình bằng cách thực hiện nhiều tác vụ đồng thời. Trong Python, module threading
cung cấp các công cụ để tạo và quản lý thread.
Tạo và Khởi Chạy Thread trong Python
Để tạo và khởi chạy thread trong Python, bạn có thể sử dụng module threading
. Dưới đây là các bước cơ bản để tạo và khởi chạy thread:
- Import module
threading
. - Định nghĩa một hàm hoặc một lớp để thực hiện tác vụ.
- Tạo một đối tượng
Thread
và truyền hàm hoặc lớp vào đó. - Gọi phương thức
start()
để khởi chạy thread.
Ví Dụ Cơ Bản
python
import threading
def print_numbers():
for i in range(1, 6):
print(i)
# Tạo một đối tượng Thread
thread = threading.Thread(target=print_numbers)
# Khởi chạy thread
thread.start()
# Đợi thread hoàn thành
thread.join()
print("Thread đã hoàn thành.")
Kết Quả:
1
2
3
4
5
Thread đã hoàn thành.
Trong ví dụ trên, chúng ta đã tạo và khởi chạy một thread để in ra các số từ 1 đến 5.
Sử Dụng Lớp để Tạo Thread
Ngoài việc sử dụng hàm, bạn cũng có thể sử dụng lớp để tạo thread bằng cách kế thừa từ lớp threading.Thread
và ghi đè phương thức run()
.
Ví Dụ
python
import threading
class PrintNumbersThread(threading.Thread):
def run(self):
for i in range(1, 6):
print(i)
# Tạo và khởi chạy thread
thread = PrintNumbersThread()
thread.start()
# Đợi thread hoàn thành
thread.join()
print("Thread đã hoàn thành.")
Kết Quả:
1
2
3
4
5
Thread đã hoàn thành.
Trong ví dụ trên, chúng ta đã tạo một lớp PrintNumbersThread
kế thừa từ threading.Thread
và ghi đè phương thức run()
để thực hiện tác vụ in ra các số từ 1 đến 5.
Truyền Tham Số vào Thread
Bạn có thể truyền tham số vào thread bằng cách sử dụng đối số args
khi tạo đối tượng Thread
.
Ví Dụ
python
import threading
def print_numbers(n):
for i in range(1, n + 1):
print(i)
# Tạo và khởi chạy thread với tham số
thread = threading.Thread(target=print_numbers, args=(5,))
thread.start()
# Đợi thread hoàn thành
thread.join()
print("Thread đã hoàn thành.")
Kết Quả:
1
2
3
4
5
Thread đã hoàn thành.
Trong ví dụ trên, chúng ta đã truyền tham số 5
vào hàm print_numbers
khi tạo thread.
Đồng Bộ Hóa Thread
Khi làm việc với nhiều thread, việc đồng bộ hóa là rất quan trọng để tránh các vấn đề như race condition. Python cung cấp các công cụ như Lock
, RLock
, Semaphore
, và Event
để đồng bộ hóa thread.
Sử Dụng Lock
Lock
là một công cụ đồng bộ hóa đơn giản, cho phép chỉ một thread truy cập vào một đoạn mã tại một thời điểm.
Ví Dụ
python
import threading
lock = threading.Lock()
def print_numbers():
with lock:
for i in range(1, 6):
print(i)
# Tạo và khởi chạy nhiều thread
threads = []
for _ in range(3):
thread = threading.Thread(target=print_numbers)
threads.append(thread)
thread.start()
# Đợi tất cả các thread hoàn thành
for thread in threads:
thread.join()
print("Tất cả các thread đã hoàn thành.")
Kết Quả:
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
Tất cả các thread đã hoàn thành.
Trong ví dụ trên, Lock
đảm bảo rằng chỉ một thread có thể truy cập vào đoạn mã in ra các số từ 1 đến 5 tại một thời điểm.
Sử Dụng RLock
RLock
(Reentrant Lock) là một loại lock có thể được khóa nhiều lần bởi cùng một thread mà không gây ra deadlock.
Ví Dụ
python
import threading
rlock = threading.RLock()
def print_numbers():
with rlock:
for i in range(1, 6):
print(i)
# Tạo và khởi chạy nhiều thread
threads = []
for _ in range(3):
thread = threading.Thread(target=print_numbers)
threads.append(thread)
thread.start()
# Đợi tất cả các thread hoàn thành
for thread in threads:
thread.join()
print("Tất cả các thread đã hoàn thành.")
Kết Quả:
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
Tất cả các thread đã hoàn thành.
Trong ví dụ trên, RLock
đảm bảo rằng cùng một thread có thể khóa nhiều lần mà không gây ra deadlock.
Sử Dụng Semaphore
Semaphore
là một công cụ đồng bộ hóa cho phép một số lượng giới hạn các thread truy cập vào một tài nguyên cụ thể.
Ví Dụ
python
import threading
semaphore = threading.Semaphore(2)
def print_numbers():
with semaphore:
for i in range(1, 6):
print(i)
# Tạo và khởi chạy nhiều thread
threads = []
for _ in range(5):
thread = threading.Thread(target=print_numbers)
threads.append(thread)
thread.start()
# Đợi tất cả các thread hoàn thành
for thread in threads:
thread.join()
print("Tất cả các thread đã hoàn thành.")
Kết Quả:
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
Tất cả các thread đã hoàn thành.
Trong ví dụ trên, Semaphore
cho phép tối đa hai thread truy cập vào đoạn mã in ra các số từ 1 đến 5 tại một thời điểm.
Sử Dụng Event
Event
là một công cụ đồng bộ hóa cho phép một thread chờ đợi một sự kiện cụ thể xảy ra.
Ví Dụ
python
import threading
import time
event = threading.Event()
def wait_for_event():
print("Thread đang chờ sự kiện...")
event.wait()
print("Sự kiện đã xảy ra!")
def trigger_event():
time.sleep(2)
print("Kích hoạt sự kiện!")
event.set()
# Tạo và khởi chạy các thread
thread1 = threading.Thread(target=wait_for_event)
thread2 = threading.Thread(target=trigger_event)
thread1.start()
thread2.start()
# Đợi tất cả các thread hoàn thành
thread1.join()
thread2.join()
print("Tất cả các thread đã hoàn thành.")
Kết Quả:
Thread đang chờ sự kiện...
Kích hoạt sự kiện!
Sự kiện đã xảy ra!
Tất cả các thread đã hoàn thành.
Trong ví dụ trên, Event
cho phép thread1
chờ đợi cho đến khi thread2
kích hoạt sự kiện.
Sử Dụng Queue
để Giao Tiếp Giữa Các Thread
Queue
là một công cụ đồng bộ hóa cho phép các thread giao tiếp với nhau một cách an toàn.
Ví Dụ
python
import threading
import queue
import time
def producer(q):
for i in range(5):
item = f"Item {i}"
q.put(item)
print(f"Produced {item}")
time.sleep(1)
def consumer(q):
while True:
item = q.get()
if item is None:
break
print(f"Consumed {item}")
q.task_done()
# Tạo một hàng đợi
q = queue.Queue()
# Tạo và khởi chạy các thread
producer_thread = threading.Thread(target=producer, args=(q,))
consumer_thread = threading.Thread(target=consumer, args=(q,))
producer_thread.start()
consumer_thread.start()
# Đợi producer hoàn thành
producer_thread.join()
# Đặt None vào hàng đợi để báo hiệu cho consumer dừng lại
q.put(None)
# Đợi consumer hoàn thành
consumer_thread.join()
print("Tất cả các thread đã hoàn thành.")
Kết Quả:
Produced Item 0
Consumed Item 0
Produced Item 1
Consumed Item 1
Produced Item 2
Consumed Item 2
Produced Item 3
Consumed Item 3
Produced Item 4
Consumed Item 4
Tất cả các thread đã hoàn thành.
Trong ví dụ trên, Queue
cho phép producer_thread
và consumer_thread
giao tiếp với nhau một cách an toàn.
Kết Luận
Thread là một công cụ mạnh mẽ trong Python, giúp tăng hiệu suất và cải thiện trải nghiệm người dùng bằng cách thực hiện nhiều tác vụ đồng thời. Python cung cấp module threading
với nhiều công cụ để tạo và quản lý thread, bao gồm Thread
, Lock
, RLock
, Semaphore
, Event
, và Queue
. Hiểu rõ và sử dụng đúng các công cụ này sẽ giúp bạn viết mã Python hiệu quả và dễ bảo trì hơn.
Hy vọng bài viết này đã giúp bạn hiểu rõ hơn về cách tạo và khởi chạy thread trong Python và cách sử dụng các công cụ đồng bộ hóa để quản lý thread một cách hiệu quả.