Làm cách nào để đảm bảo chỉ một chuỗi có thể sử dụng tệp tại một thời điểm Python?

Đa luồng và đa xử lý là hai cách để đạt được đa nhiệm [nghĩ rằng tính toán phân tán. ] bằng Python. Đa nhiệm rất hữu ích trong việc chạy các chức năng và mã song song, chẳng hạn như chia nhỏ phép tính toán học thành nhiều phần nhỏ hơn hoặc tách các mục trong vòng lặp for nếu chúng độc lập với nhau. Bài viết này sẽ giới thiệu và so sánh sự khác nhau giữa đa luồng và đa xử lý, khi nào thì sử dụng từng phương thức và cách triển khai chúng trong Python

Cập nhật. Bài viết này là một phần của loạt bài. Xem các chủ đề “trong 10 phút” khác tại đây

Mục lục
Đa luồng so với. đa xử lý

Theo định nghĩa chính thức, đa luồng đề cập đến khả năng bộ xử lý thực thi đồng thời nhiều luồng, trong đó mỗi luồng chạy một quy trình. Trong khi đa xử lý đề cập đến khả năng của một hệ thống chạy nhiều bộ xử lý đồng thời, trong đó mỗi bộ xử lý có thể chạy một hoặc nhiều luồng

hình 1. Đa luồng so với. Đa xử lý — Ảnh của tác giả

Từ sơ đồ trên, chúng ta có thể thấy rằng trong đa luồng [sơ đồ ở giữa], nhiều luồng chia sẻ cùng một mã, dữ liệu và tệp nhưng chạy trên một thanh ghi và ngăn xếp khác nhau. Đa xử lý [sơ đồ bên phải] nhân một bộ xử lý — sao chép mã, dữ liệu và tệp, điều này phát sinh nhiều chi phí hơn

Đa luồng hữu ích cho các quy trình liên kết với IO, chẳng hạn như đọc tệp từ mạng hoặc cơ sở dữ liệu vì mỗi luồng có thể chạy đồng thời quy trình liên kết với IO. Đa xử lý rất hữu ích cho các quy trình liên kết với CPU, chẳng hạn như các tác vụ tính toán nặng vì nó sẽ có lợi khi có nhiều bộ xử lý;

Lưu ý rằng việc sử dụng đa luồng cho các quy trình liên kết với CPU có thể làm chậm hiệu suất do các tài nguyên cạnh tranh đảm bảo chỉ một luồng có thể thực thi tại một thời điểm và chi phí phát sinh khi xử lý nhiều luồng

Mặt khác, đa xử lý có thể được sử dụng cho các quy trình liên kết với IO. Tuy nhiên, chi phí quản lý nhiều quy trình cao hơn quản lý nhiều luồng như minh họa ở trên. Bạn có thể nhận thấy rằng đa xử lý có thể dẫn đến mức sử dụng CPU cao hơn do chương trình sử dụng nhiều lõi CPU, điều này được mong đợi

Đa luồng như một chức năng Python

Đa luồng có thể được triển khai bằng thư viện tích hợp Python threading và được thực hiện theo thứ tự sau,

  1. Tạo chủ đề. Mỗi luồng được gắn thẻ vào một hàm Python với các đối số của nó
  2. Bắt đầu thực hiện nhiệm vụ
  3. Đợi luồng hoàn tất thực thi. Hữu ích để đảm bảo hoàn thành hoặc 'điểm kiểm tra'

Trong đoạn mã bên dưới, các bước trên được triển khai, cùng với khóa luồng [Dòng 22] để xử lý các tài nguyên cạnh tranh, đây là tùy chọn trong trường hợp của chúng tôi

Có một vài quan sát đáng chú ý

  • Dòng 12–15. Các quy trình chạy trên các luồng khác nhau [ID luồng], nhưng với cùng một bộ xử lý [ID quy trình]
  • dòng 8. Thay vào đó, nếu time.sleep[sleep_duration] được triển khai giữa việc mua và giải phóng khóa, các luồng sẽ chạy tuần tự và sẽ không tiết kiệm được bất kỳ khoản thời gian nào — bạn có thể thử
Đa luồng như một lớp Python

Đối với người dùng thích Lập trình hướng đối tượng, đa luồng có thể được triển khai dưới dạng lớp Python kế thừa từ lớp cha threading.Thread. Một lợi ích từ việc sử dụng các lớp thay vì các hàm là khả năng chia sẻ các biến thông qua các đối tượng lớp

Sự khác biệt giữa việc triển khai đa luồng như một chức năng so với. lớp sẽ ở Bước 1 [Tạo chủ đề] vì một luồng hiện được gắn thẻ cho một phương thức lớp thay vì một hàm. Các bước tiếp theo để gọi t1.start[]t1.join[] vẫn giữ nguyên

import time

class Sleep[threading.Thread]:
def __init__[self, sleep_duration]:
self.sleep_duration = sleep_duration

def sleep[self]:
time.sleep[self.sleep_duration]

if __name__ == "__main__":
# Create thread
sleep_class = Sleep[2]
t1 = threading.Thread[target=sleep_class.sleep]
Đa xử lý dưới dạng Hàm Python

Đa xử lý có thể được triển khai với thư viện tích hợp Python multiprocessing bằng hai phương thức khác nhau — Quy trình và Nhóm

Phương thức xử lý tương tự như phương thức đa luồng ở trên, trong đó mỗi Quy trình được gắn thẻ cho một hàm với các đối số của nó. Trong đoạn mã bên dưới, chúng ta có thể thấy rằng thời gian dành cho đa xử lý lâu hơn đa luồng vì có nhiều chi phí hơn khi chạy nhiều bộ xử lý

Phương pháp nhóm cho phép người dùng xác định số lượng công nhân và phân phối tất cả các quy trình cho các bộ xử lý có sẵn theo lịch trình Nhập trước xuất trước, tự động xử lý lập lịch quy trình. Phương thức nhóm được sử dụng để chia một hàm thành nhiều phần nhỏ bằng cách sử dụng map hoặc starmap[dòng 19] — chạy cùng một hàm với các đối số đầu vào khác nhau. Trong khi phương thức Process được sử dụng để chạy các chức năng khác nhau

Hy vọng bài viết này đã giới thiệu khái niệm về đa luồng và đa xử lý, và khi nào thì sử dụng từng phương pháp. Các ví dụ về Python là các đoạn mã khung mà bạn có thể thay thế bằng các hàm của mình và bạn đã sẵn sàng để sử dụng

Nhiều chủ đề có thể đọc cùng một tệp cùng một lúc không?

Nhiều luồng cũng có thể đọc đồng thời dữ liệu từ cùng một tệp FITS, miễn là tệp được mở độc lập bởi từng luồng . Điều này phụ thuộc vào hệ điều hành để xử lý chính xác việc đọc cùng một tệp bằng nhiều quy trình.

Nhiều luồng có thể chạy cùng lúc trong Python không?

Trên thực tế, một quy trình Python không thể chạy các luồng song song nhưng nó có thể chạy chúng đồng thời thông qua chuyển ngữ cảnh trong các hoạt động liên kết I/O . Hạn chế này thực sự được thi hành bởi GIL. Khóa phiên dịch toàn cầu Python [GIL] ngăn các luồng trong cùng một quy trình được thực thi cùng một lúc.

Hai luồng có thể ghi vào cùng một tệp Python không?

Việc ghi đồng thời vào cùng một tệp từ nhiều luồng không phải là luồng an toàn và có thể dẫn đến tình trạng tương tranh . An toàn luồng có nghĩa là việc ghi hoặc nối thêm vào cùng một tệp từ nhiều luồng có thể dẫn đến tình trạng tương tranh.

Python chỉ sử dụng một luồng?

Nói chung, Python chỉ sử dụng một luồng để thực thi tập hợp các câu lệnh đã viết . Điều này có nghĩa là trong python, chỉ có một luồng sẽ được thực thi tại một thời điểm.

Chủ Đề