2010-02-20 30 views
12

Tôi có hai luồng, một chuỗi ghi vào một tệp và một chuỗi khác định kỳ di chuyển tệp đến một vị trí khác. Bài viết luôn gọi open trước khi viết tin nhắn và gọi close sau khi viết tin nhắn. Mover sử dụng shutil.move để thực hiện việc di chuyển.Nhiều chuỗi Python truy cập cùng một tệp

Tôi thấy rằng sau khi di chuyển đầu tiên được thực hiện, người viết không thể ghi vào tệp nữa, tức là kích thước của tệp luôn bằng 0 sau lần di chuyển đầu tiên. Tôi có làm điều gì sai?

Trả lời

25

Khóa là một giải pháp khả thi, nhưng tôi thích kiến ​​trúc tổng quát của việc có mỗi tài nguyên bên ngoài (bao gồm một tệp) được xử lý bởi một chuỗi riêng biệt. Các chủ đề khác gửi yêu cầu công việc tới luồng chuyên dụng trên một cá thể Queue.Queue (và cung cấp một hàng đợi riêng của chúng như là một phần của tham số yêu cầu công việc nếu chúng cần kết quả), chuỗi chuyên dụng dành phần lớn thời gian chờ đợi trên .get hàng đợi và bất cứ khi nào nó nhận được một yêu cầu đi vào và thực hiện nó (và trả về kết quả trên hàng đợi đã được chuyển vào nếu cần).

Tôi đã cung cấp các ví dụ chi tiết về phương pháp này, ví dụ: trong "Python in a Nutshell". Hàng đợi của Python thực chất là an toàn và đơn giản hóa cuộc sống của bạn rất nhiều.

Trong số những ưu điểm của kiến ​​trúc này là nó dịch trơn tru để multiprocessing nếu và khi bạn quyết định chuyển một số công việc để một quá trình riêng biệt thay vì một thread riêng biệt (ví dụ như để tận dụng đa lõi) - multiprocessing cung cấp riêng của mình làm việc theo kiểu Queue để thực hiện chuyển đổi mượt mà như tơ ;-).

+0

Nếu tôi viết một thư viện phải an toàn chỉ nhưng không phải lúc nào cũng được sử dụng trong chuỗi. Tôi có nên sử dụng phương pháp này hoặc xem một khóa không? Tôi không chắc liệu thư viện của tôi có nên sinh ra các chủ đề mới nếu nó chỉ được sử dụng một luồng không. Giải pháp tốt nhất cho một số biến của chủ đề có thể là một trong những gì? –

7

Khi hai luồng truy cập cùng một tài nguyên, những điều kỳ lạ sẽ xảy ra. Để tránh điều đó, luôn khóa tài nguyên. Python có tiện ích threading.Lock cho điều đó, cũng như một số công cụ khác (xem tài liệu về mô-đun threading).

4

Check-out http://www.evanfosmark.com/2009/01/cross-platform-file-locking-support-in-python/

Bạn có thể sử dụng một khóa đơn giản với mã của mình, như được viết bởi Evan Fosmark trong một câu hỏi StackOverflow cũ:

from filelock import FileLock 

with FileLock("myfile.txt"): 
    # work with the file as it is now locked 
    print("Lock acquired.") 

Một trong những thư viện thanh lịch hơn mà tôi từng thấy .

+0

bạn có chắc chắn điều này có thể được kết hợp với các tệp di chuyển xung quanh không? –

+3

Mã của Evan Fosmark áp dụng để đồng bộ hóa nhiều * quy trình *, chứ không phải * chủ đề *. Theo gợi ý của Eli, tôi sẽ sử dụng 'threading.Lock' hoặc' threading.RLock'. –

+0

Theo dõi, liên kết trong bài đăng này không còn hoạt động nữa. Mỗi [Câu trả lời của Evan cho một câu hỏi liên quan ở đây] (http://stackoverflow.com/a/498505/760905) bạn cũng có thể tìm thấy mã tại https://github.com/dmfrey/FileLock – MartyMacGyver

Các vấn đề liên quan