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.

Sử dụng Semaphore trong Python

Trong bài viết này, bạn sẽ học cách sử dụng Semaphore trong Python để kiểm soát số lượng luồng có thể truy cập vào một tài nguyên chia sẻ cùng lúc. Semaphore là một công cụ đồng bộ hóa mạnh mẽ giúp ngăn chặn các vấn đề đồng thời như race conditions, nơi mà nhiều luồng cố gắng truy cập vào tài nguyên cùng một lúc và gây ra sự cố. Bằng cách sử dụng Semaphore, bạn có thể đảm bảo rằng một số lượng giới hạn các luồng có thể truy cập vào tài nguyên chia sẻ, giúp tăng tính ổn định và an toàn cho ứng dụng của bạn.

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ề Semaphore trong Python

Semaphore trong Python là một công cụ đồng bộ hóa cho phép bạn kiểm soát truy cập vào một tài nguyên chia sẻ. Về cơ bản, Semaphore là một bộ đếm kèm theo một khóa, giới hạn số lượng luồng có thể truy cập vào tài nguyên chia sẻ cùng một lúc.

Semaphore giúp ngăn chặn các vấn đề đồng bộ hóa luồng như race condition, nơi mà nhiều luồng cố gắng truy cập vào tài nguyên cùng một lúc và làm ảnh hưởng lẫn nhau.

Semaphore duy trì một bộ đếm. Khi một luồng muốn truy cập tài nguyên chia sẻ, semaphore sẽ kiểm tra bộ đếm. Nếu bộ đếm lớn hơn 0, nó sẽ giảm bộ đếm và cho phép luồng truy cập tài nguyên. Nếu bộ đếm bằng 0, semaphore sẽ chặn luồng cho đến khi bộ đếm lớn hơn 0.

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

Semaphore có hai thao tác chính:

  • Acquire: Thao tác này kiểm tra bộ đếm và giảm nó nếu lớn hơn 0. Nếu bộ đếm bằng 0, semaphore sẽ chặn luồng cho đến khi một luồng khác giải phóng semaphore.
  • Release: Thao tác này tăng bộ đếm, cho phép các luồng khác có thể acquire nó.

Sử dụng Semaphore trong Python

Để sử dụng semaphore, bạn thực hiện các bước sau:

  • Đầu tiên, import mô-đun threading:
import threading
  • Tạo một đối tượng Semaphore và xác định số lượng luồng có thể acquire cùng lúc:
semaphore = threading.Semaphore(3)

Trong ví dụ này, chúng ta tạo một đối tượng Semaphore chỉ cho phép tối đa ba luồng acquire cùng lúc.

  • Acquire semaphore từ một luồng bằng cách gọi phương thức acquire():
semaphore.acquire()

Nếu bộ đếm semaphore bằng 0, luồng sẽ đợi cho đến khi một luồng khác giải phóng semaphore. Khi đã acquire semaphore, bạn có thể thực hiện một phần mã quan trọng.

  • Giải phóng semaphore sau khi chạy xong phần mã quan trọng bằng cách gọi phương thức release():

semaphore.release()

Để đảm bảo semaphore được acquire và release một cách chính xác, ngay cả khi có ngoại lệ xảy ra trong quá trình chạy phần mã quan trọng, bạn có thể sử dụng câu lệnh with:

with semaphore:
    # Mã trong khối này đã acquire semaphore
    # Thực hiện các thao tác trên tài nguyên chia sẻ
    # ...
# Semaphore được release ngoài khối with

Ví dụ về sử dụng Semaphore trong Python

Ví dụ sau đây minh họa cách sử dụng semaphore để giới hạn số lượng tải xuống đồng thời tối đa là ba bằng cách sử dụng multithreading trong Python:

import threading
import urllib.request

MAX_CONCURRENT_DOWNLOADS = 3
semaphore = threading.Semaphore(MAX_CONCURRENT_DOWNLOADS)

def download(url):
    with semaphore:
        print(f"Downloading {url}...")
        
        response = urllib.request.urlopen(url)
        data = response.read()
        
        print(f"Finished downloading {url}")
        return data

def main():
    urls = [
        'https://www.ietf.org/rfc/rfc791.txt',
        'https://www.ietf.org/rfc/rfc792.txt',
        'https://www.ietf.org/rfc/rfc793.txt',
        'https://www.ietf.org/rfc/rfc794.txt',
        'https://www.ietf.org/rfc/rfc795.txt',
    ]

    threads = []
    for url in urls:
        thread = threading.Thread(target=download, args=(url,))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

if __name__ == '__main__':
    main()

Kết quả:

Downloading https://www.ietf.org/rfc/rfc791.txt...
Downloading https://www.ietf.org/rfc/rfc792.txt...
Downloading https://www.ietf.org/rfc/rfc793.txt...
Finished downloading https://www.ietf.org/rfc/rfc792.txt
Downloading https://www.ietf.org/rfc/rfc794.txt...
Finished downloading https://www.ietf.org/rfc/rfc791.txt
Downloading https://www.ietf.org/rfc/rfc795.txt...
Finished downloading https://www.ietf.org/rfc/rfc793.txt
Finished downloading https://www.ietf.org/rfc/rfc794.txt
Finished downloading https://www.ietf.org/rfc/rfc795.txt

Kết quả này cho thấy chỉ tối đa ba luồng có thể tải xuống cùng lúc:

Downloading https://www.ietf.org/rfc/rfc791.txt...
Downloading https://www.ietf.org/rfc/rfc792.txt...
Downloading https://www.ietf.org/rfc/rfc793.txt...

Khi số lượng luồng đạt tới ba, luồng tiếp theo phải đợi semaphore được giải phóng bởi một luồng khác.

Ví dụ, luồng #2 hoàn thành và giải phóng semaphore, và luồng tiếp theo bắt đầu tải xuống URL https://www.ietf.org/rfc/rfc794.txt:

Finished downloading https://www.ietf.org/rfc/rfc792.txt
Downloading https://www.ietf.org/rfc/rfc794.txt...

Kết bài

Sử dụng semaphore trong Python để kiểm soát số lượng luồng có thể truy cập vào một tài nguyên chia sẻ cùng lúc giúp ngăn chặn các vấn đề đồng bộ hóa và đảm bảo an toàn cho các hoạt động trên tài nguyên chia sẻ. Bằng cách sử dụng các phương thức acquire() và release(), bạn có thể quản lý truy cập vào tài nguyên một cách hiệu quả và tránh các vấn đề như race conditions. Hy vọng rằng qua bài viết này, bạn đã hiểu rõ hơn về cách sử dụng semaphore trong Python để xây dựng các ứng dụng đa luồng an toàn và đáng tin cậy.

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