Python - Luồng Chính
Chào, các nhà lập trình đam mê! Hôm nay, chúng ta sẽ bắt đầu hành trình hấp dẫn vào thế giới luồng (threading) của Python, tập trung vào luồng chính. Là người giáo viên khoa học máy tính bạn thân thiện, tôi đang ở đây để hướng dẫn bạn qua chủ đề thú vị này. Đừng lo nếu bạn mới bắt đầu học lập trình – chúng ta sẽ bắt đầu từ các khái niệm cơ bản và dần dần đi lên. Vậy, hãy lấy ly đồ uống yêu thích của bạn, thoải mái ngồi xuống và hãy bắt đầu!
Luồng Chính Là Gì?
Trước khi bước vào chi tiết, hãy hiểu rõ luồng là gì. Hãy tưởng tượng bạn đang đọc một cuốn sách khi đồng thời nghe nhạc. Đầu óc của bạn đang thực hiện hai nhiệm vụ đồng thời – đó tương tự như các luồng hoạt động trong lập trình. Luồng chính như là câu chuyện chính của chương trình của bạn, là luồng mà bắt đầu khi bạn chạy script Python của mình.
Luồng Chính Trong Hành Động
Hãy bắt đầu với một ví dụ đơn giản để thấy luồng chính trong hành động:
import threading
import time
def print_current_thread():
print(f"Luồng hiện tại: {threading.current_thread().name}")
print_current_thread()
time.sleep(2)
print("Luồng chính vẫn đang chạy!")
Khi bạn chạy script này, bạn sẽ thấy gì đó như sau:
Luồng hiện tại: MainThread
Luồng chính vẫn đang chạy!
Trong ví dụ này, chúng ta sử dụng mô-đun threading
để truy cập thông tin về luồng hiện tại. Hàm time.sleep(2)
chỉ là để thêm một chút gián đoạn, như một dấu three dots hấp dẫn trong câu chuyện lập trình của chúng ta.
Truy Cập Luồng Chính
Bây giờ khi chúng ta đã thấy luồng chính trong hành động, hãy học cách truy cập nó trực tiếp. Python cung cấp cách tiếp cận tiện lợi như sau:
import threading
main_thread = threading.main_thread()
print(f"Tên luồng chính: {main_thread.name}")
print(f"ID luồng chính: {main_thread.ident}")
Script này sẽ đầu ra gì đó như sau:
Tên luồng chính: MainThread
ID luồng chính: 140735268892672
Tham chiếu ident
là mã số duy nhất cho luồng. Nó giống như số an sinh xã hội cho các luồng – không có hai luồng nào có cùng một ID.
Kiểm Tra Xem Chúng Ta Có Ở Trong Luồng Chính Không
Đôi khi, bạn có thể muốn kiểm tra xem mã của bạn có đang chạy trong luồng chính không. Dưới đây là cách bạn có thể làm điều đó:
import threading
def am_i_main():
return threading.current_thread() == threading.main_thread()
print(f"Chúng ta có ở trong luồng chính không? {am_i_main()}")
def not_main():
print(f"Chúng ta có ở trong luồng chính bây giờ không? {am_i_main()}")
thread = threading.Thread(target=not_main)
thread.start()
thread.join()
Script này sẽ đầu ra:
Chúng ta có ở trong luồng chính không? True
Chúng ta có ở trong luồng chính bây giờ không? False
Trong ví dụ này, chúng ta tạo một luồng mới chạy hàm not_main()
. Khi chúng ta gọi am_i_main()
từ luồng mới này, nó trả về False
.
Hành Vi Của Luồng Chính Trong Python
Luồng chính trong Python có một số hành vi thú vị mà bạn cần hiểu rõ. Hãy khám phá chúng!
Luồng Chính Và Kết Thúc Chương Trình
Một hành vi chính của luồng chính là khi nó hoàn thành thực hiện, toàn bộ chương trình Python thường kết thúc. Hãy xem điều này trong hành động:
import threading
import time
def long_task():
print("Bắt đầu nhiệm vụ dài...")
time.sleep(5)
print("Nhiệm vụ dài hoàn thành!")
thread = threading.Thread(target=long_task)
thread.start()
print("Luồng chính đã hoàn thành!")
Nếu bạn chạy script này, bạn sẽ có thể thấy:
Bắt đầu nhiệm vụ dài...
Luồng chính đã hoàn thành!
Lưu ý rằng thông điệp "Nhiệm vụ dài hoàn thành!" không bao giờ xuất hiện. Điều này là vì luồng chính đã hoàn thành và chương trình kết thúc trước khi nhiệm vụ dài có thể hoàn thành.
Luồng Daemon Và Luồng Non-Daemon
Để hiểu rõ hơn về hành vi của luồng chính, chúng ta cần nói về luồng daemon. Một luồng daemon như một nhiệm vụ nền không ngăn cản chương trình kết thúc. Hãy sửa đổi ví dụ trước đó của chúng ta:
import threading
import time
def long_task():
print("Bắt đầu nhiệm vụ dài...")
time.sleep(5)
print("Nhiệm vụ dài hoàn thành!")
thread = threading.Thread(target=long_task)
thread.daemon = True # Đặt luồng làm daemon
thread.start()
print("Luồng chính đã hoàn thành!")
Đầu ra sẽ tương tự như trước. Tuy nhiên, nếu chúng ta loại bỏ dòng thread.daemon = True
, chúng ta sẽ thấy:
Bắt đầu nhiệm vụ dài...
Luồng chính đã hoàn thành!
Nhiệm vụ dài hoàn thành!
Điều này là vì các luồng non-daemon (mặc định) ngăn cản chương trình kết thúc cho đến khi họ hoàn thành.
Luồng Chính Chờ Luồng Khác
Thường xuyên, bạn sẽ muốn luồng chính của bạn chờ các luồng khác hoàn thành trước khi kết thúc chương trình. Python cung cấp cách đơn giản để làm điều này:
import threading
import time
def task(name):
print(f"Nhiệm vụ {name} bắt đầu...")
time.sleep(2)
print(f"Nhiệm vụ {name} hoàn thành!")
threads = []
for i in range(3):
t = threading.Thread(target=task, args=(f"T{i}",))
threads.append(t)
t.start()
for t in threads:
t.join()
print("Tất cả các nhiệm vụ đã hoàn thành!")
Script này sẽ đầu ra:
Nhiệm vụ T0 bắt đầu...
Nhiệm vụ T1 bắt đầu...
Nhiệm vụ T2 bắt đầu...
Nhiệm vụ T0 hoàn thành!
Nhiệm vụ T1 hoàn thành!
Nhiệm vụ T2 hoàn thành!
Tất cả các nhiệm vụ đã hoàn thành!
Phương thức join()
khiến luồng chính chờ đến khi mỗi luồng hoàn thành công việc của mình.
Bảng Các Phương Thức Luồng Hữu Ích
Dưới đây là bảng một số phương thức luồng hữu ích mà chúng ta đã thảo luận và một số phương thức khác:
Phương thức | Mô tả |
---|---|
threading.current_thread() |
Trả về đối tượng Thread hiện tại |
threading.main_thread() |
Trả về đối tượng Thread chính |
Thread.start() |
Bắt đầu hoạt động của luồng |
Thread.join() |
Chờ đến khi luồng kết thúc |
Thread.is_alive() |
Trả về xem luồng còn sống hay không |
Thread.setDaemon(bool) |
Đặt cờ daemon cho luồng |
Kết Luận
Xin chúc mừng! Bạn đã bước ra những bước đầu tiên vào thế giới luồng (threading) của Python. Chúng ta đã bàn về luồng chính, cách truy cập nó, hành vi của nó và cách nó tương tác với các luồng khác. Nhớ rằng, luồng có thể là một chủ đề phức tạp, nhưng với thực hành, bạn sẽ cảm thấy dễ dàng hơn với nó.
Khi kết thúc, tôi nhớ lại một câu nói của nhà khoa học máy tính nổi tiếng Alan Kay: "Cách tốt nhất để dự đoán tương lai là để khám phá nó." Với kiến thức mới về luồng Python, bạn đã có đủ công cụ để tạo ra những chương trình đa luồng tuyệt vời!
Hãy tiếp tục lập trình, học hỏi và quan trọng nhất, hãy thích thú! Chờ đợi chuyến gặp lại sau, chúc mừng các bạn luồng!
Credits: Image by storyset