-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path16.DesignDistributedLockManager(DLM).py
More file actions
72 lines (57 loc) · 2.51 KB
/
16.DesignDistributedLockManager(DLM).py
File metadata and controls
72 lines (57 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# Design a Distributed Lock Manager (DLM) that allows multiple clients to
# safely acquire and release locks on shared resources. Ensure
# that only one client can hold a lock at a time, and locks automatically expire
# after a timeout if not released.
# Simulate concurrency using threads in Python.
import threading, time
class DistributedLockManager:
def __init__(self, timeout = 5):
self.lock_table = {}
self.global_lock = threading.Lock()
self.timeout = timeout
threading.Thread(target = self.cleanup_expired_locks, daemon = True).start()
def acquire_lock(self, resource, client_id):
with self.global_lock:
if resource not in self.lock_table:
self.lock_table[resource] = (client_id, time.time())
print(f"{client_id} acquired lock on {resource}")
return True
else:
owner, t = self.lock_table[resource]
if time.time() - t > self.timeout:
print(f"{client_id} took expired lock on {resource}")
self.lock_table[resource] = (client_id, time.time())
return True
else:
print(f"{client_id} waiting... {resource} locked by {owner}")
return False
def release_lock(self, resource, client_id):
with self.global_lock:
if resource in self.lock_table and self.lock_table[resource][0] == client_id:
del self.lock_table[resource]
print(f"{client_id} released lock on {resource}")
def cleanup_expired_locks(self):
while True:
with self.global_lock:
now = time.time()
expired = [r for r, (o, t) in self.lock_table.items() if now - t > self.timeout]
for r in expired:
print(f"Lock on {r} expired and removed.")
del self.lock_table[r]
time.sleep(1)
def client_task(dlm, cid, resource):
for _ in range(3):
if dlm.acquire_lock(resource, cid):
time.sleep(2)
dlm.release_lock(resource, cid)
else:
time.sleep(1)
if __name__ == "__main__":
dlm = DistributedLockManager(timeout=4)
threads = []
for i in range(3):
t = threading.Thread(target=client_task, args=(dlm, f"Client-{i+1}", "resA"))
threads.append(t)
t.start()
for t in threads:
t.join()