PYTHON CONCURRENCY
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.

Đối tượng Threading Event trong Python

Trong lập trình đa luồng, việc giao tiếp giữa các luồng và đồng bộ hóa hoạt động của chúng là rất quan trọng để đảm bảo chương trình hoạt động hiệu quả và không gặp phải lỗi. Python cung cấp nhiều công cụ mạnh mẽ để hỗ trợ quá trình này, trong đó đối tượng Event từ module threading là một phương tiện hiệu quả và dễ sử dụng. Event cho phép các luồng phối hợp hoạt động thông qua cơ chế báo hiệu, giúp một luồng có thể thông báo cho các luồng khác biết khi nào nên tiếp tục thực hiện nhiệm vụ. Bài viết này sẽ giới thiệu chi tiết về đối tượng Event, cách sử dụng nó để giao tiếp giữa các luồng, và cung cấp các ví dụ minh họa cụ thể để bạn đọc có thể nắm bắt và áp dụng vào thực tế.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Giới thiệu về đối tượng Threading Event trong Python

Đôi khi, bạn cần giao tiếp giữa các luồng trong chương trình của mình. Để làm điều này, bạn có thể sử dụng khóa (mutex) và một biến boolean.

Tuy nhiên, Python cung cấp một cách tốt hơn để giao tiếp giữa các luồng bằng cách sử dụng lớp Event từ module threading.

Lớp Event cung cấp một cách đơn giản nhưng hiệu quả để phối hợp giữa các luồng: một luồng báo hiệu sự kiện trong khi các luồng khác chờ sự kiện đó.

Bài viết này được đăng tại [free tuts .net]

Đối tượng Event bọc một cờ boolean có thể được đặt (True) hoặc xóa (False). Nhiều luồng có thể chờ sự kiện được đặt trước khi tiếp tục hoặc có thể đặt lại sự kiện về trạng thái xóa.

Các bước sử dụng đối tượng Event

Nhập Event từ module threading:

from threading import Event

Tạo một đối tượng Event mới:

event = Event()

Mặc định, sự kiện không được đặt (xóa). Phương thức is_set() của đối tượng event sẽ trả về False:

if event.is_set():
   # ...

Đặt một sự kiện bằng phương thức set():

event.clear()

Các luồng có thể chờ sự kiện được đặt thông qua phương thức wait():

event.wait()

Phương thức wait() sẽ chặn luồng hiện tại cho đến khi sự kiện được đặt. Bạn cũng có thể chỉ định thời gian chờ thông qua tham số timeout:

event.wait(timeout=5) # chờ trong 5 giây

Ví dụ về sử dụng Threading Event trong Python

Ví dụ sau minh họa cách sử dụng đối tượng Event để giao tiếp giữa các luồng:

from threading import Thread, Event
from time import sleep

def task(event: Event, id: int) -> None:
    print(f'Thread {id} started. Waiting for the signal....')
    event.wait()
    print(f'Received signal. The thread {id} was completed.')

def main() -> None:
    event = Event()

    t1 = Thread(target=task, args=(event,1))
    t2 = Thread(target=task, args=(event,2))

    t1.start()
    t2.start()

    print('Blocking the main thread for 3 seconds...')
    sleep(3) 
    event.set()

if __name__ == '__main__':
    main()

Cách hoạt động của mã:

Định nghĩa hàm task() nhận một đối tượng Event và một số nguyên:

def task(event: Event, id: int) -> None:
    print(f'Thread {id} started. Waiting for the signal....')
    event.wait()
    print(f'Received signal. The thread {id} was completed.')

Trong hàm task(), chúng ta gọi phương thức wait() của đối tượng event để chờ sự kiện được đặt bởi luồng chính.

Tạo đối tượng Event bên trong hàm main():

event = Event()

Tạo hai luồng con thực thi hàm task() với cùng đối tượng event và id khác nhau:

t1 = Thread(target=task, args=(event,1))
t2 = Thread(target=task, args=(event,2))

Bắt đầu cả hai luồng:

t1.start()
t2.start()

Chặn luồng chính trong 3 giây:

sleep(3)

Vì hàm task() gọi phương thức wait() của đối tượng event, cả hai luồng t1 và t2 sẽ chờ sự kiện được đặt trước khi tiếp tục.

Đặt sự kiện bằng cách gọi phương thức set() từ luồng chính:

event.set()

Cả hai luồng t1 và t2 sẽ được thông báo và tiếp tục thực thi cho đến khi kết thúc.

Ví dụ thực tế về sử dụng Threading Event trong Python

Ví dụ sau minh họa cách sử dụng threading event để đồng bộ hóa giữa hai luồng:

  • Luồng thứ nhất tải xuống một tệp văn bản từ URL https://www.ietf.org/rfc/rfc793.txt, khi hoàn thành, nó thông báo cho luồng thứ hai để đếm số từ trong tệp đã tải xuống.
  • Luồng thứ hai bắt đầu và chờ tín hiệu hoàn thành từ luồng thứ nhất. Khi nhận được tín hiệu, nó bắt đầu đếm số từ trong tệp đã tải xuống.
from threading import Thread, Event
from urllib import request

def download_file(url, event):
    # Tải tệp từ URL
    print(f"Downloading file from {url}...")
    filename, _ = request.urlretrieve(url, "rfc793.txt")

    # Tệp đã được tải xuống, đặt sự kiện
    event.set()

def process_file(event):
    print("Waiting for the file to be downloaded...")
    event.wait()  # Chờ sự kiện được đặt

    # Tệp đã được tải xuống, bắt đầu xử lý
    print("File download completed. Starting file processing...")

    # Đếm số từ trong tệp
    word_count = 0
    with open("rfc793.txt", "r") as file:
        for line in file:
            words = line.split()
            word_count += len(words)

    # In số từ trong tệp
    print(f"Number of words in the file: {word_count}")

def main():
    # Tạo đối tượng Event
    event = Event()

    # Tạo và bắt đầu luồng tải tệp
    download_thread = Thread(target=download_file, 
                             args=("https://www.ietf.org/rfc/rfc793.txt", event))
    download_thread.start()

    # Tạo và bắt đầu luồng xử lý tệp
    process_thread = Thread(target=process_file, args=(event,))
    process_thread.start()

    # Chờ cả hai luồng hoàn thành
    download_thread.join()
    process_thread.join()

    print("Main thread finished.")

if __name__ == '__main__':
    main()

Kết bài

Trong lập trình đa luồng, việc sử dụng đối tượng Event của lớp threading mang lại nhiều lợi ích cho việc giao tiếp và đồng bộ hóa giữa các luồng. Như đã trình bày, bạn có thể sử dụng các phương thức set(), clear(), is_set(), và wait() để kiểm soát và quản lý sự kiện giữa các luồng một cách dễ dàng và hiệu quả.

Phương thức set() cho phép bạn kích hoạt sự kiện, báo hiệu cho các luồng khác biết rằng chúng có thể tiếp tục thực hiện nhiệm vụ của mình. Phương thức clear() giúp xóa sự kiện, đưa nó về trạng thái ban đầu để sẵn sàng cho lần sử dụng tiếp theo. Với is_set(), bạn có thể kiểm tra xem sự kiện đã được kích hoạt hay chưa, và wait() sẽ giúp các luồng chờ đợi cho đến khi sự kiện được đặt.

Những kiến thức này không chỉ giúp bạn viết các chương trình đa luồng mạnh mẽ và hiệu quả hơn, mà còn giúp bạn tránh được các vấn đề tiềm ẩn như deadlock và race condition. Hy vọng rằng bài viết đã cung cấp cho bạn một cái nhìn rõ ràng và đầy đủ về cách sử dụng Event trong Python, giúp bạn tự tin hơn trong việc lập trình đa luồng.

Cùng chuyên mục:

Cách thêm Progress Bar trong Python với chỉ một dòng Code

Cách thêm Progress Bar trong Python với chỉ một dòng Code

Toán tử Walrus Operator- Tính năng mới trong Python 3.8

Toán tử Walrus Operator- Tính năng mới trong Python 3.8

Cách nạp dữ liệu Machine Learning từ File trong Python

Cách nạp dữ liệu Machine Learning từ File trong Python

Hướng dẫn sử dụng Google Sheets API với Python

Hướng dẫn sử dụng Google Sheets API với Python

Xây dựng  web Python tự động hóa Twitter | Flask, Heroku, Twitter API & Google Sheets API

Xây dựng web Python tự động hóa Twitter | Flask, Heroku, Twitter API & Google Sheets API

Xây dựng Web Machine Learning đẹp mắt với Streamlit và Scikit-learn trong Python

Xây dựng Web Machine Learning đẹp mắt với Streamlit và Scikit-learn trong Python

Hướng dẫn tạo Chatbot đơn giản bằng PyTorch

Hướng dẫn tạo Chatbot đơn giản bằng PyTorch

11 mẹo và thủ thuật để viết Code Python hiệu quả hơn

11 mẹo và thủ thuật để viết Code Python hiệu quả hơn

Hướng dẫn làm ứng dụng TODO với Flask dành cho người mới bắt đầu trong Python

Hướng dẫn làm ứng dụng TODO với Flask dành cho người mới bắt đầu trong Python

Hướng dẫn viết Snake Game bằng Python

Hướng dẫn viết Snake Game bằng Python

Cách sử dụng chế độ interactive trong Python

Cách sử dụng chế độ interactive trong Python

Cách sử dụng Python Debugger với hàm breakpoint()

Cách sử dụng Python Debugger với hàm breakpoint()

Xây dựng ứng dụng Web Style Transfer với PyTorch và Streamlit

Xây dựng ứng dụng Web Style Transfer với PyTorch và Streamlit

Cách cài đặt Jupyter Notebook trong môi trường Conda và thêm Kernel

Cách cài đặt Jupyter Notebook trong môi trường Conda và thêm Kernel

Hướng dẫn xây dựng ứng dụng dự đoán giá cổ phiếu bằng Python

Hướng dẫn xây dựng ứng dụng dự đoán giá cổ phiếu bằng Python

Hướng dẫn tạo ứng dụng AI hội thoại với NVIDIA Jarvis trong Python

Hướng dẫn tạo ứng dụng AI hội thoại với NVIDIA Jarvis trong Python

Hỗ trợ Async trong Django 3.1

Hỗ trợ Async trong Django 3.1

8 mẹo tái cấu trúc Python giúp mã sạch hơn và Pythonic

8 mẹo tái cấu trúc Python giúp mã sạch hơn và Pythonic

Ý nghĩa của if __name__ ==

Ý nghĩa của if __name__ == "__main__" trong Python

Cách xóa phần tử trong danh sách Python

Cách xóa phần tử trong danh sách Python

Top