9

Tôi có một ổ đĩa mạng (Z: \) được chia sẻ bởi nhiều máy tính Windows. Có thể thực hiện khóa máy chéo bằng cách tạo/xóa các tệp trên ổ đĩa mạng này không?Triển khai khóa phân phối bằng các tệp

Ví dụ: hai máy tính, A và B, muốn ghi vào tài nguyên được chia sẻ có ID là 123 cùng một lúc.

Một trong các máy tính, giả sử A, khóa tài nguyên trước bằng cách tạo một tệp rỗng Z: \ locks \ 123. Khi B thấy có tệp khóa có tên là "123", B biết tài nguyên 123 đang được người khác sử dụng, vì vậy phải đợi Z: \ locks \ 123 bị xóa bởi A trước khi có thể truy cập nguồn.

Giống như phần quan trọng trong đa luồng, nhưng tôi muốn thực hiện trên nhiều máy.

Tôi đang cố triển khai bằng Python. Dưới đây là những gì tôi đã đưa ra:

import os 
import time 


def lock_it(lock_id): 

    lock_path = "Z:\\locks\\" + lock_id 
    while os.path.exists(lock_path): 
     time.sleep(5) # wait for 5 seconds 

    # create the lock file 
    lock_file = open(lock_path, "w") 
    lock_file.close() 


def unlock_it(lock_id): 

    # delete the lock file 
    lock_path = "Z:\\locks\\" + lock_id 
    if os.path.exists(lock_path): 
     os.remove(lock_path) 

Điều này sẽ không hoạt động vì có thể có nhiều quá trình thoát trạng thái chờ và tạo tệp khóa cùng một lúc.

Vì vậy, một lần nữa, câu hỏi là: Có thể triển khai cơ chế khóa máy chéo trên bộ nhớ dùng chung không?

Trả lời

5

... sắp xếp.

Trước tiên, bạn nên tạo thư mục khóa thay vì tệp khóa. Tạo một thư mục (xem os.mkdir) sẽ thất bại nếu thư mục đã tồn tại, vì vậy bạn có thể có được khóa như thế này:

while True: 
    try: 
     os.mkdir(r"z:\my_lock") 
     return 
    except OSError as e: 
     if e.errno != 21: # Double check that errno will be the same on Windows 
      raise 
     time.sleep(5) 

Thứ hai (và đây là nơi mà các "loại" do thỏa thuận), bạn sẽ muốn có một số cách để ý khi người cầm khóa đã chết. Một cách đơn giản để thực hiện việc này có thể là thỉnh thoảng họ cập nhật một tệp trong thư mục khóa. Sau đó, nếu khách hàng nhận thấy rằng tập tin đó đã không được cập nhật trong một thời gian, họ có thể loại bỏ các thư mục và cố gắng để có được khóa mình.

+1

Làm cách nào để thêm thời gian chờ? tức là, Sau một khoảng thời gian, nói 60 giây, khóa sẽ tự động được giải phóng. Giả sử rằng thời gian khóa sẽ không vượt quá thời gian chờ này. Tôi có thể nhận được thời gian khóa với time.time() - os.path.getctime ("Z: \ my_lock") để kiểm tra xem khóa có quá hạn hay không. – eliang

2

Điều này sẽ không hoạt động gần như bạn có thể hy vọng. Bạn sẽ có các vấn đề khác như ổ đĩa mạng biến mất, trong trường hợp đó tất cả các quy trình của bạn sẽ bị kẹt hoặc nghĩ rằng không có ai đang giữ khóa.

Tôi đề nghị bạn nên xem một số thứ như ZooKeeper. Bạn sẽ có thể tạo các khóa đồng bộ và khôi phục trong trường hợp thất bại mạng. Khuôn khổ đằng sau các khóa phân phối phức tạp hơn nhiều sau đó tạo một tệp trên ổ đĩa mạng.

+0

Tôi đã suy nghĩ Memcache hoặc phần mềm xếp hàng như Beanstalk. – aitchnyu