forked from M-Ahtasham-Ul-Haq/python-coding-questions
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththreads_demo.py
More file actions
164 lines (135 loc) · 4.32 KB
/
threads_demo.py
File metadata and controls
164 lines (135 loc) · 4.32 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
162
163
164
"""
🧵 Python Multithreading Practice
This script demonstrates core concepts of Python's threading module, including
parallel execution, race conditions, thread safety, and performance comparison.
"""
import threading
import time
import requests
# 1. ✅ Create two threads that run concurrently
def task1():
print("Task 1 is running...")
def task2():
print("Task 2 is running...")
# 2. ✅ Use threading to download files in parallel
def download_file(url):
response = requests.get(url)
print(f"Downloaded {len(response.content)} bytes from {url}")
# 3. ✅ Simulate a race condition
counter = 0
def race_condition():
global counter
for _ in range(100000):
temp = counter
temp += 1
counter = temp
# 4. ✅ Use Lock to handle race condition
lock = threading.Lock()
safe_counter = 0
def thread_safe_increment():
global safe_counter
for _ in range(100000):
with lock:
temp = safe_counter
temp += 1
safe_counter = temp
# 5. ✅ Thread that counts numbers and prints
def count_numbers(name):
for i in range(5):
print(f"{name} counting: {i}")
time.sleep(0.5)
# 6. ✅ Create a multi-threaded counter
def multi_threaded_counter():
threads = []
for i in range(3):
thread = threading.Thread(target=count_numbers, args=(f"Thread-{i+1}",))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
# 7. ✅ Demonstrate Thread.join() usage
def show_join():
def simple_task():
print("Starting task...")
time.sleep(1)
print("Task completed.")
thread = threading.Thread(target=simple_task)
thread.start()
thread.join() # Wait until thread finishes
print("Main thread resumes after join.")
# 8. ✅ Use daemon threads
def background_logger():
while True:
print("[Daemon] Logging...")
time.sleep(1)
# 9. ✅ Time how long multi-threaded vs. normal code takes
def count_slow():
for _ in range(5):
time.sleep(1)
def performance_compare():
start = time.time()
count_slow()
count_slow()
print("⏳ Sequential Time:", time.time() - start)
start = time.time()
t1 = threading.Thread(target=count_slow)
t2 = threading.Thread(target=count_slow)
t1.start()
t2.start()
t1.join()
t2.join()
print("⚡ Parallel Time:", time.time() - start)
# 10. ✅ Thread-safe increment of shared variable using Lock
thread_safe_value = 0
def safe_increment():
global thread_safe_value
for _ in range(100000):
with lock:
thread_safe_value += 1
def run_safe_threads():
t1 = threading.Thread(target=safe_increment)
t2 = threading.Thread(target=safe_increment)
t1.start()
t2.start()
t1.join()
t2.join()
print("✅ Thread-safe value:", thread_safe_value)
# === Run All Tasks ===
if __name__ == "__main__":
print("\n1. Concurrent Threads:")
t1 = threading.Thread(target=task1)
t2 = threading.Thread(target=task2)
t1.start()
t2.start()
t1.join()
t2.join()
print("\n2. Parallel File Download:")
urls = ["https://httpbin.org/image/png", "https://httpbin.org/image/jpeg"]
for url in urls:
threading.Thread(target=download_file, args=(url,)).start()
print("\n3. Race Condition Example:")
threads = [threading.Thread(target=race_condition) for _ in range(2)]
[t.start() for t in threads]
[t.join() for t in threads]
print("❌ Race Condition Counter:", counter)
print("\n4. Race Condition Fixed with Lock:")
threads = [threading.Thread(target=thread_safe_increment) for _ in range(2)]
[t.start() for t in threads]
[t.join() for t in threads]
print("✅ Safe Counter with Lock:", safe_counter)
print("\n5. Counting Thread:")
count_thread = threading.Thread(target=count_numbers, args=("Counter",))
count_thread.start()
count_thread.join()
print("\n6. Multi-threaded Counter:")
multi_threaded_counter()
print("\n7. Thread Join Demo:")
show_join()
print("\n8. Daemon Thread (runs in background):")
daemon = threading.Thread(target=background_logger, daemon=True)
daemon.start()
time.sleep(3) # Let daemon run briefly
print("\n9. Performance Comparison:")
performance_compare()
print("\n10. Thread-safe Increment:")
run_safe_threads()