PHP
Python

Trang chủ

Cách tạo thread trong Python dành cho người mới

Ngôn ngữ Python là một ngôn ngữ lập trình đa mục đích, nổi tiếng với cú pháp dễ đọc, dễ học và tính ứng dụng cao. Trong lĩnh vực phát triển web, Python thường được sử dụng thông qua các framework như Django và Flask để xây dựng các ứng dụng web mạnh mẽ, bảo mật và dễ mở rộng. Trong chuyên mục này, Vietnix không chỉ cung cấp kiến thức nền tảng về ngôn ngữ Python mà còn hướng dẫn chi tiết cách xây dựng các ứng dụng web thực tế, sử dụng các framework phổ biến và áp dụng các kỹ thuật tiên tiến. Vietnix cam kết liên tục cập nhật những bài viết mới nhất về các tính năng mới của Python, các thư viện hỗ trợ hữu ích và những phương pháp tốt nhất, giúp bạn khai thác tối đa sức mạnh của Python và hoàn thiện kỹ năng lập trình web của mình.
html
CSS
javascript
sql
python
php
c
c++
bootstrap
react
mysql
reactjs
vuejs
Javascript Tutorials
17/03/2025
15 phút đọc
Theo dõi Vietnix trên

Cách tạo thread trong Python dành cho người mới

Thread trong Python là một kỹ thuật giúp chương trình thực thi nhiều tác vụ cùng lúc mà không cần chờ tác vụ trước hoàn thành. Quá trình này giúp tăng hiệu suất, đặc biệt khi xử lý các tác vụ tốn thời gian như tải dữ liệu hoặc xử lý file. Trong bài viết này, mình sẽ hướng dẫn cách tạo thread trong Python một cách đơn giản, phù hợp cho người mới bắt đầu.

Những điểm chính

  • Cách tạo thread với hàm trong Python: Hiểu cách sử dụng thư viện threading để tạo và quản lý thread bằng cách gọi hàm.
  • Tạo thread bằng cách mở rộng thread class: Biết cách tạo thread bằng cách kế thừa thread class, giúp tổ chức code gọn gàng và dễ quản lý hơn.
  • Tạo thread bằng hàm start_new_thread(): Sử dụng start_new_thread() từ module _thread để tạo thread nhanh chóng với mã nguồn đơn giản.
  • Biết thêm Vietnix – Nhà cung cấp dịch vụ lưu trữ tốc độ cao, giải pháp tối ưu cho website cần hiệu suất cao.
  • Câu hỏi thường gặp: Giải đáp những thắc mắc phổ biến khi làm việc với thread trong Python.

Cách tạo thread với hàm trong Python

Trong Python, bạn có thể tạo thread bằng cách sử dụng thread class từ module threading. Phương pháp này cho phép bạn khởi tạo và thực thi một thread bằng cách truyền một hàm vào đối tượng Thread. Dưới đây là các bước cơ bản để tạo một thread:

  • Xác định hàm mà bạn muốn thread thực thi.
  • Tạo một đối tượng Thread, truyền vào hàm mục tiêu và các tham số cần thiết.
  • Gọi phương thức start() để bắt đầu thực thi thread.
  • Nếu cần, bạn sử dụng phương thức join() để chờ thread hoàn thành trước khi tiếp tục chương trình.
Cách tạo thread trong Python với hàm
Cách tạo thread trong Python với hàm

Đoạn code sau minh họa cách tạo và chạy nhiều thread đồng thời trong Python. Mỗi thread thực thi một tác vụ khác nhau, chẳng hạn như kiểm tra trạng thái dịch vụ hosting, tính toán hiệu suất hoặc hiển thị thông báo hệ thống:

from threading import Thread  
import time  
def check_service_status(service_name):  
    print(f"Đang kiểm tra trạng thái của {service_name}...")  
    time.sleep(2)  
    print(f"{service_name} đang hoạt động ổn định.")  
def calculate_performance(metric):  
    print(f"Đang tính toán hiệu suất dựa trên {metric}...")  
    time.sleep(3)  
    print(f"Hiệu suất {metric}: 98.5%")  
def display_notification():  
    print("Thông báo: Hệ thống đang hoạt động bình thường.")  
Thread(target=check_service_status, args=("VPS Vietnix",)).start()  
Thread(target=calculate_performance, args=("CPU Usage",)).start()  
Thread(target=display_notification).start()

Tạo thread bằng cách mở rộng thread class

Một cách khác để tạo thread trong Python là mở rộng (kế thừa) lớp Thread. Cách này giúp tổ chức code rõ ràng hơn, đặc biệt khi bạn cần quản lý nhiều thread với hành vi phức tạp. Các bước thực hiện như sau:

  • Định nghĩa một lớp mới kế thừa từ threading.Thread.
  • Ghi đè phương thức __init__ để truyền các tham số cần thiết.
  • Ghi đè phương thức run() để xác định hành vi của thread.

Giả sử, bạn cần kiểm tra hiệu suất của một dịch vụ hosting bằng cách chạy nhiều thread kiểm tra phản hồi từ máy chủ. Bạn có thể sử dụng threading.Thread để thực hiện điều này một cách hiệu quả:

import threading
import time
import requests
class ServerCheckThread(threading.Thread):
    def __init__(self, thread_id, name, url):
        threading.Thread.__init__(self)
        self.thread_id = thread_id
        self.name = name
        self.url = url
    def run(self):
        print(f"Bắt đầu {self.name}")
        check_server_response(self.name, self.url)
        print(f"Hoàn thành {self.name}")
def check_server_response(thread_name, url):
    try:
        response = requests.get(url)
        print(f"{thread_name}: Phản hồi từ {url} - Mã trạng thái: {response.status_code}")
    except Exception as e:
        print(f"{thread_name}: Lỗi khi kết nối đến {url} - {e}")
# Danh sách URL cần kiểm tra
urls = [
    "https://vietnix.vn",
    "https://example.com"
]
# Tạo và chạy các thread kiểm tra
threads = []
for i, url in enumerate(urls):
    thread = ServerCheckThread(i + 1, f"Thread-{i+1}", url)
    threads.append(thread)
    thread.start()
# Chờ tất cả các thread hoàn thành
for thread in threads:
    thread.join()
print("Kiểm tra hoàn tất.")
  • Kết quả dự kiến:

Bắt đầu Thread-1
Bắt đầu Thread-2
Thread-1: Phản hồi từ https://vietnix.vn – Mã trạng thái: 200
Thread-2: Phản hồi từ https://example.com – Mã trạng thái: 200
Hoàn thành Thread-1
Hoàn thành Thread-2
Kiểm tra hoàn tất.

Ví dụ trên cho thấy cách sử dụng nhiều thread để kiểm tra phản hồi từ các máy chủ một cách nhanh chóng. Điều này đặc biệt hữu ích khi bạn cần giám sát nhiều website cùng lúc, giúp tiết kiệm thời gian so với việc kiểm tra tuần tự.

Tạo thread bằng hàm start_new_thread()

Hàm start_new_thread() trong module _thread được sử dụng để tạo một thread mới trong chương trình đang chạy. Đây là một cách tiếp cận ở mức thấp để thực hiện threading trong Python. Tuy nhiên, so với module threading, _thread đơn giản hơn nhưng không hỗ trợ nhiều tính năng nâng cao như quản lý trạng thái thread hay đồng bộ hóa tài nguyên.

Cú pháp của _thread.start_new_thread()

_thread.start_new_thread ( function, args[, kwargs] )

Trong đó:

    • function: Hàm mà thread mới sẽ thực thi.

    • args: Danh sách tham số cần truyền vào hàm, được truyền dưới dạng tuple.

    • kwargs: Tham số tùy chọn, có thể truyền dưới dạng dictionary.

Giả sử, bạn đang muốn kiểm tra hiệu suất hệ thống bằng cách chạy các tác vụ song song, chẳng hạn như ghi log truy cập của người dùng trên website hosting. Bạn có thể sử dụng _thread.start_new_thread() để tạo hai thread ghi log với tốc độ khác nhau:

import _thread
import time
# Hàm ghi log giả lập
def log_access(thread_name, delay):
    for count in range(1, 6):
        time.sleep(delay)
        print(f"Luồng: {thread_name} - Ghi log lần {count}")
# Tạo hai thread ghi log song song
try:
    _thread.start_new_thread(log_access, ("Log-1", 2,))
    _thread.start_new_thread(log_access, ("Log-2", 4,))
except:
    print("Lỗi: Không thể khởi động luồng")
# Duy trì chương trình để thread chạy
while True:
    pass
  • Kết quả dự kiến:

Luồng: Log-1 – Ghi log lần 1
Luồng: Log-2 – Ghi log lần 1
Luồng: Log-1 – Ghi log lần 2
Luồng: Log-1 – Ghi log lần 3
Luồng: Log-2 – Ghi log lần 2
Luồng: Log-1 – Ghi log lần 4
Luồng: Log-1 – Ghi log lần 5
Luồng: Log-2 – Ghi log lần 3
Luồng: Log-2 – Ghi log lần 4
Luồng: Log-2 – Ghi log lần 5

Chương trình sẽ chạy liên tục do while True: giữ chương trình không kết thúc. Bạn có thể nhấn Ctrl + C để dừng chương trình. Sử dụng _thread.start_new_thread() phù hợp với các tác vụ nhẹ, yêu cầu khởi động nhanh và không cần quản lý trạng thái thread phức tạp. Nếu cần nhiều tính năng hơn, bạn nên sử dụng module threading.

Vietnix – Nhà cung cấp dịch vụ lưu trữ tốc độ cao

Vietnix là một trong những đơn vị uy tín hàng đầu trong lĩnh vực web hostingVPSthuê máy chủ và domain, cung cấp giải pháp lưu trữ mạnh mẽ với hiệu suất vượt trội. Hạ tầng hiện đại, hệ thống tối ưu và đội ngũ kỹ thuật hỗ trợ 24/7 giúp website của bạn hoạt động nhanh, ổn định, đảm bảo trải nghiệm mượt mà cho người dùng. Với hơn 80.000 khách hàng tin tưởng, Vietnix là lựa chọn lý tưởng để nâng cao tốc độ và bảo mật dữ liệu. Liên hệ ngay để trải nghiệm dịch vụ hosting chất lượng cao!

Thông tin liên hệ:

  • Hotline: 18001093
  • Email: sales@vietnix.com.vn 
  • Địa chỉ: 265 Hồng Lạc, Phường 10, Quận Tân Bình, Thành Phố Hồ Chí Minh.
  • Website: https://vietnix.vn/

Câu hỏi thường gặp

Có thể sử dụng thread trong Python để tối ưu hiệu suất của các tác vụ liên quan đến I/O như thế nào?

Thread trong Python có thể tối ưu hiệu suất của các tác vụ liên quan đến I/O bằng cách tận dụng khả năng chuyển đổi ngữ cảnh (context switching) khi một thread đang chờ I/O, giúp các thread khác tiếp tục chạy mà không bị chặn. Các cách tối ưu bao gồm:
Dùng threading.Thread() để chạy nhiều tác vụ I/O song song, chẳng hạn như đọc/ghi file, gửi yêu cầu HTTP, truy vấn database.
Sử dụng ThreadPoolExecutor để quản lý số lượng thread và tái sử dụng chúng hiệu quả.
Tránh sử dụng thread cho các tác vụ CPU-bound, vì Python có GIL (Global Interpreter Lock) giới hạn khả năng chạy song song của CPU.
Kết hợp thread với queue (queue.Queue()) để phân phối công việc giữa các thread và tránh điều kiện race (race condition).
Dùng concurrent.futures để dễ dàng thu thập kết quả và xử lý lỗi khi chạy nhiều thread cùng lúc.
Với các tác vụ I/O như tải dữ liệu từ API, xử lý file lớn hoặc giao tiếp với database, thread giúp cải thiện tốc độ thực thi đáng kể mà không tiêu tốn nhiều tài nguyên CPU.

Nếu một thread bị lỗi, làm sao để xử lý lỗi mà không ảnh hưởng đến các thread khác?

Để xử lý lỗi trong một thread mà không ảnh hưởng đến các thread khác, bạn có thể áp dụng các phương pháp sau:
Dùng try-except trong thread: Bọc code thực thi trong try-except để bắt và xử lý lỗi ngay trong thread.
Sử dụng concurrent.futures.ThreadPoolExecutor: Trả về đối tượng Future, cho phép bắt lỗi và xử lý một cách an toàn.
Dùng logging thay vì print(): Ghi lại lỗi mà không làm gián đoạn chương trình chính.
Thiết lập cơ chế giám sát thread: Dùng một thread khác để theo dõi và khởi động lại thread bị lỗi nếu cần.
Dùng threading.Event() hoặc queue.Queue(): Gửi tín hiệu hoặc thông báo lỗi đến thread chính để xử lý hợp lý.
Không để lỗi làm dừng toàn bộ chương trình: Tránh dùng sys.exit() hoặc các lệnh có thể dừng toàn bộ tiến trình khi chỉ một thread gặp lỗi.

Nếu một biến toàn cục được sử dụng trong nhiều thread, làm sao để đảm bảo tính nhất quán của dữ liệu?

Để đảm bảo tính nhất quán của dữ liệu khi một biến toàn cục được sử dụng trong nhiều thread, bạn có thể áp dụng các biện pháp sau:
Sử dụng khóa (Lock): Dùng threading.Lock() để đảm bảo chỉ một thread có thể truy cập biến tại một thời điểm.
Dùng threading.RLock() nếu có nhiều khóa liên quan: Tránh deadlock khi một thread cần khóa nhiều lần.
Dùng threading.Semaphore() nếu muốn giới hạn số thread truy cập biến.
Sử dụng threading.Condition() cho các trường hợp cần đồng bộ hóa nâng cao.
Dùng queue.Queue() thay vì biến toàn cục: Tránh truy cập đồng thời bằng cách sử dụng hàng đợi an toàn cho thread.
Dùng biến threading.local() nếu mỗi thread cần một bản sao riêng của biến.
Sử dụng atomic operations với threading.Event() hoặc atomic module (Python 3.9+).
Lựa chọn phương pháp phù hợp tùy vào mức độ phức tạp của chương trình và yêu cầu về hiệu suất.

Khi nào nên sử dụng ThreadPoolExecutor thay vì tạo thread thủ công bằng threading.Thread()?

Bạn nên sử dụng ThreadPoolExecutor thay vì threading.Thread() trong các trường hợp sau:
Quản lý số lượng thread tự động: Hạn chế việc tạo quá nhiều thread gây quá tải hệ thống.
Tái sử dụng thread: Giúp tiết kiệm tài nguyên thay vì tạo thread mới cho mỗi tác vụ.
Đơn giản hóa xử lý tác vụ đồng thời: Không cần quản lý thủ công danh sách thread.
Dễ dàng lấy kết quả từ thread: Trả về đối tượng Future, giúp truy xuất kết quả có tổ chức hơn.
Xử lý lỗi hiệu quả hơn: Cho phép bắt lỗi từ thread một cách rõ ràng.
Tuy nhiên, nếu cần kiểm soát từng thread riêng lẻ, xử lý tác vụ CPU-bound hoặc chỉ chạy một vài thread, threading.Thread() có thể phù hợp hơn.

Lời kết

Qua bài viết này, bạn đã nắm được các cách tạo thread trong Python, từ sử dụng hàm đến kế thừa class và tận dụng các thư viện hỗ trợ. Việc sử dụng thread giúp chương trình xử lý nhiều tác vụ đồng thời, đặc biệt hiệu quả với các tác vụ I/O. Tuy nhiên, bạn cũng cần lưu ý về quản lý tài nguyên và đồng bộ dữ liệu để tránh lỗi. Nếu bạn có bất kỳ thắc mắc nào hãy để lại bình luận ngay bên dưới, mình sẽ giải đáp nhanh nhất! Cảm ơn bạn đã theo dõi bài viết!

Mọi người cũng xem:

Cao Lê Viết Tiến

PHP Leader
tại
Vietnix

Kết nối với mình qua

Icon Quote
Icon Quote

Học lập trình online cùng vietnix

Học lập trình online cùng Vietnix

PHPXem thêmThu gọn