Python - Tạo luồng (Thread)

Xin chào, các nhà lập trình Python đam mê! Hôm nay, chúng ta sẽ bơi lội vào thế giới huyền ảo của các luồng. Đừng lo lắng nếu bạn chưa từng nghe về luồng trước đây – chúng ta sẽ bắt đầu từ đầu và làm theo từng bước. Khi hết bài học này, bạn sẽ tạo luồng như một chuyên gia!

Python - Creating a Thread

Luồng là gì?

Trước khi chúng ta bắt đầu tạo luồng, hãy hiểu rõ luồng là gì. Hãy tưởng tượng bạn đang nấu một bữa ăn phức tạp. Bạn không thực hiện mọi thứ theo thứ tự – bạn có thể đang nấu mỳ ở một bề mặt trong khi bạn đang cắt rau ở bàn cắt. Điều này tương tự như cách các luồng hoạt động trong lập trình. Chúng cho phép các phần khác nhau của chương trình chạy đồng thời, làm cho mã của bạn hiệu quả hơn.

Tạo Luồng bằng Hàm

Cách đơn giản nhất để tạo luồng trong Python là bằng cách sử dụng một hàm. Hãy bắt đầu với một ví dụ cơ bản:

import threading
import time

def in_so():
for i in range(5):
print(f"Số {i}")
time.sleep(1)

# Tạo một luồng
luong = threading.Thread(target=in_so)

# Bắt đầu luồng
luong.start()

print("Luồng chính tiếp tục chạy")

# Đợi luồng kết thúc
luong.join()

print("Luồng đã kết thúc")

Hãy phân tích:

  1. Chúng ta nhập thư viện threading, cung cấp các công cụ cần thiết để làm việc với luồng.
  2. Chúng ta định nghĩa một hàm đơn giản in_so() in các số từ 0 đến 4, có một giây tạm dừng giữa mỗi lần in.
  3. Chúng ta tạo một luồng bằng cách sử dụng threading.Thread(), chỉ định hàm của chúng ta làm target.
  4. Chúng ta bắt đầu luồng bằng luong.start().
  5. Chương trình chính tiếp tục chạy, in "Luồng chính tiếp tục chạy".
  6. Chúng ta sử dụng luong.join() để đợi luồng của chúng ta kết thúc trước khi tiếp tục.

Khi bạn chạy đoạn mã này, bạn sẽ thấy "Luồng chính tiếp tục chạy" được in ngay lập tức, trong khi các số đang được in ở nền.

Tạo Luồng bằng Cách Mở Rộng Lớp Thread

Một cách khác để tạo luồng là mở rộng lớp Thread. Phương pháp này hữu ích khi bạn muốn tạo một đối tượng luồng có thể tái sử dụng. Dưới đây là một ví dụ:

import threading
import time

class InSo(threading.Thread):
def __init__(self, ten):
threading.Thread.__init__(self)
self.ten = ten

def run(self):
for i in range(5):
print(f"{self.ten}: Số {i}")
time.sleep(1)

# Tạo hai luồng
luong1 = InSo("Luồng 1")
luong2 = InSo("Luồng 2")

# Bắt đầu các luồng
luong1.start()
luong2.start()

print("Luồng chính tiếp tục chạy")

# Đợi cả hai luồng kết thúc
luong1.join()
luong2.join()

print("Cả hai luồng đã kết thúc")

Trong ví dụ này:

  1. Chúng ta định nghĩa một lớp InSo mở rộng threading.Thread.
  2. Chúng ta ghi đè phương thức __init__ để chấp nhận tên cho luồng của chúng ta.
  3. Chúng ta ghi đè phương thức run, được gọi khi luồng bắt đầu.
  4. Chúng ta tạo hai thể hiện của lớp InSo của chúng ta và bắt đầu chúng.
  5. Cả hai luồng chạy đồng thời, in các số của chúng.

Phương pháp này giúp chúng ta có nhiều kiểm soát hơn đối với luồng và cho phép chúng ta dễ dàng tạo nhiều thể hiện.

Tạo Luồng bằng Cách Sử dụng hàm start_new_thread()

Có một cách thứ ba để tạo luồng trong Python, cụ thể là bằng cách sử dụng hàm start_new_thread() của mô-đun _thread. Tuy nhiên, phương pháp này được coi là cấp độ thấp và không khuyến khích sử dụng cho hầu hết các trường hợp. Dưới đây là một ví dụ đầy đủ:

import _thread
import time

def in_so(ten_luong):
for i in range(5):
print(f"{ten_luong}: Số {i}")
time.sleep(1)

# Bắt đầu hai luồng mới
try:
_thread.start_new_thread(in_so, ("Luồng 1",))
_thread.start_new_thread(in_so, ("Luồng 2",))
except:
print("Lỗi: không thể bắt đầu luồng")

# Giữ luồng chính sống
time.sleep(6)
print("Luồng chính thoát")

Phương pháp này ít linh hoạt hơn và không cung cấp nhiều kiểm soát như các phương pháp trước đó. Nó cũng khó đợi các luồng hoàn thành khi sử dụng phương pháp này.

So sánh Các Phương pháp Tạo Luồng

Dưới đây là so sánh nhanh chóng về ba phương pháp mà chúng ta đã thảo luận:

Phương pháp Ưu điểm Nhược điểm
Sử dụng hàm Dễ thực hiện, tốt cho các nhiệm vụ một lần ít tái sử dụng, kiểm soát hạn chế
Mở rộng lớp Thread Tái sử dụng, nhiều kiểm soát, hướng đối tượng Đột phá hơn để thiết lập
start_new_thread() Kiểm soát cấp độ thấp Khó quản lý, ít linh hoạt, không khuyến khích

Kết luận

Xin chúc mừng! Bạn đã bước ra đầu tiên vào thế giới của luồng trong Python. Chúng ta đã trình bày ba cách khác nhau để tạo luồng, mỗi cách có ưu và đối tượng sử dụng riêng. Nhớ rằng, luồng có thể làm cho chương trình của bạn hiệu quả hơn, nhưng cũng giới thiệu phức tạp. Khi bạn tiếp tục hành trình Python của mình, bạn sẽ học thêm về khi và cách sử dụng luồng một cách hiệu quả.

Tiếp tục tập luyện, và sớm bạn sẽ tạo luồng như một nhà lập trình có kinh nghiệm. Chúc bạn mãi mãi hạnh phúc mã hóa!

Credits: Image by storyset