-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
161 lines (132 loc) · 4.3 KB
/
main.py
File metadata and controls
161 lines (132 loc) · 4.3 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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# main.py
"""
Reader-Writer Problem Simulator
This script spawns a number of concurrent reader and writer
threads to demonstrate the three types of RW Locks.
"""
import threading
import logging
import random
import time
import argparse
# Import all three lock classes from the 'locks' module
from rw_lock.locks import (
ReaderPriorityRWLock,
WriterPriorityRWLock,
FairRWLock
)
# --- Global Shared Resources ---
shared_buffer = []
lock = None # Will be set in main()
# ---------------------------------
# Thread Target Functions
# ---------------------------------
def writer(name: str):
"""
The target function for writer threads.
Acquires a write lock and appends to the buffer.
"""
logging.info('is waiting to write...')
with lock.write():
# --- Start Critical Section ---
logging.info('is starting to write.')
value = random.randint(1, 100)
shared_buffer.append(value)
logging.info(f'WROTE: {value} (Buffer: {shared_buffer})')
# Simulate work
time.sleep(random.uniform(0.1, 0.3))
logging.info('is finishing writing.')
# --- End Critical Section ---
def reader(name: str):
"""
The target function for reader threads.
Acquires a read lock and reads from the buffer.
"""
logging.info('is waiting to read...')
with lock.read():
# --- Start Critical Section ---
logging.info('is starting to read.')
# Simulate work
time.sleep(random.uniform(0.1, 0.3))
if not shared_buffer:
logging.info('READ: Buffer is empty.')
else:
logging.info(f'READ: Buffer state is {shared_buffer}')
logging.info('is finishing reading.')
# --- End Critical Section ---
# ---------------------------------
# Main Simulator Setup
# ---------------------------------
def main():
"""Parses args and runs the simulation."""
global lock # We need to assign the global 'lock'
parser = argparse.ArgumentParser(
description="Run a Reader-Writer lock simulation."
)
parser.add_argument(
'-t', '--num-threads',
type=int,
default=10,
help="Total number of threads to spawn."
)
parser.add_argument(
'-w', '--write-prob',
type=float,
default=0.3,
help="Probability (0.0 to 1.0) of a thread being a writer."
)
parser.add_argument(
'-p', '--priority',
choices=['reader', 'writer', 'fair'],
default='writer',
help="Set the lock priority model."
)
parser.add_argument(
'--log-level',
choices=['DEBUG', 'INFO'],
default='INFO',
help="Set the logging level."
)
args = parser.parse_args()
# --- Setup Logging ---
log_level = logging.DEBUG if args.log_level == 'DEBUG' else logging.INFO
logging.basicConfig(
level=log_level,
format='{threadName} {message}',
style='{'
)
# --- Select and instantiate the chosen lock ---
if args.priority == 'reader':
lock = ReaderPriorityRWLock()
elif args.priority == 'writer':
lock = WriterPriorityRWLock()
elif args.priority == 'fair':
lock = FairRWLock()
print(f"--- Starting {args.priority.title()}-Priority Simulation ---")
# --- Start Simulation ---
threads = []
wcount, rcount = 0, 0
print(f"Starting {args.num_threads} threads. Writer probability: {args.write_prob*100}%")
for i in range(args.num_threads):
if random.random() < args.write_prob:
# Create a Writer
wcount += 1
name = f'Writer-{wcount}'
target = writer
else:
# Create a Reader
rcount += 1
name = f'Reader-{rcount}'
target = reader
thread = threading.Thread(target=target, name=name, args=(name,))
threads.append(thread)
logging.info(f'Starting {name}...')
thread.start()
time.sleep(random.uniform(0, 0.1)) # Stagger thread starts
# --- Wait for all threads to complete ---
for thread in threads:
thread.join()
print("All threads finished.")
print(f"Final Buffer State: {shared_buffer}")
if __name__ == "__main__":
main()