Skip to content

Commit 7d2481a

Browse files
threads_demo.py
1 parent 95b226a commit 7d2481a

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed

advance/threads_demo.py

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
"""
2+
🧵 Python Multithreading Practice
3+
This script demonstrates core concepts of Python's threading module, including
4+
parallel execution, race conditions, thread safety, and performance comparison.
5+
"""
6+
7+
import threading
8+
import time
9+
import requests
10+
11+
# 1. ✅ Create two threads that run concurrently
12+
def task1():
13+
print("Task 1 is running...")
14+
15+
def task2():
16+
print("Task 2 is running...")
17+
18+
# 2. ✅ Use threading to download files in parallel
19+
def download_file(url):
20+
response = requests.get(url)
21+
print(f"Downloaded {len(response.content)} bytes from {url}")
22+
23+
# 3. ✅ Simulate a race condition
24+
counter = 0
25+
26+
def race_condition():
27+
global counter
28+
for _ in range(100000):
29+
temp = counter
30+
temp += 1
31+
counter = temp
32+
33+
# 4. ✅ Use Lock to handle race condition
34+
lock = threading.Lock()
35+
safe_counter = 0
36+
37+
def thread_safe_increment():
38+
global safe_counter
39+
for _ in range(100000):
40+
with lock:
41+
temp = safe_counter
42+
temp += 1
43+
safe_counter = temp
44+
45+
# 5. ✅ Thread that counts numbers and prints
46+
def count_numbers(name):
47+
for i in range(5):
48+
print(f"{name} counting: {i}")
49+
time.sleep(0.5)
50+
51+
# 6. ✅ Create a multi-threaded counter
52+
def multi_threaded_counter():
53+
threads = []
54+
for i in range(3):
55+
thread = threading.Thread(target=count_numbers, args=(f"Thread-{i+1}",))
56+
threads.append(thread)
57+
thread.start()
58+
for thread in threads:
59+
thread.join()
60+
61+
# 7. ✅ Demonstrate Thread.join() usage
62+
def show_join():
63+
def simple_task():
64+
print("Starting task...")
65+
time.sleep(1)
66+
print("Task completed.")
67+
68+
thread = threading.Thread(target=simple_task)
69+
thread.start()
70+
thread.join() # Wait until thread finishes
71+
print("Main thread resumes after join.")
72+
73+
# 8. ✅ Use daemon threads
74+
def background_logger():
75+
while True:
76+
print("[Daemon] Logging...")
77+
time.sleep(1)
78+
79+
# 9. ✅ Time how long multi-threaded vs. normal code takes
80+
def count_slow():
81+
for _ in range(5):
82+
time.sleep(1)
83+
84+
def performance_compare():
85+
start = time.time()
86+
count_slow()
87+
count_slow()
88+
print("⏳ Sequential Time:", time.time() - start)
89+
90+
start = time.time()
91+
t1 = threading.Thread(target=count_slow)
92+
t2 = threading.Thread(target=count_slow)
93+
t1.start()
94+
t2.start()
95+
t1.join()
96+
t2.join()
97+
print("⚡ Parallel Time:", time.time() - start)
98+
99+
# 10. ✅ Thread-safe increment of shared variable using Lock
100+
thread_safe_value = 0
101+
102+
def safe_increment():
103+
global thread_safe_value
104+
for _ in range(100000):
105+
with lock:
106+
thread_safe_value += 1
107+
108+
def run_safe_threads():
109+
t1 = threading.Thread(target=safe_increment)
110+
t2 = threading.Thread(target=safe_increment)
111+
t1.start()
112+
t2.start()
113+
t1.join()
114+
t2.join()
115+
print("✅ Thread-safe value:", thread_safe_value)
116+
117+
# === Run All Tasks ===
118+
if __name__ == "__main__":
119+
print("\n1. Concurrent Threads:")
120+
t1 = threading.Thread(target=task1)
121+
t2 = threading.Thread(target=task2)
122+
t1.start()
123+
t2.start()
124+
t1.join()
125+
t2.join()
126+
127+
print("\n2. Parallel File Download:")
128+
urls = ["https://httpbin.org/image/png", "https://httpbin.org/image/jpeg"]
129+
for url in urls:
130+
threading.Thread(target=download_file, args=(url,)).start()
131+
132+
print("\n3. Race Condition Example:")
133+
threads = [threading.Thread(target=race_condition) for _ in range(2)]
134+
[t.start() for t in threads]
135+
[t.join() for t in threads]
136+
print("❌ Race Condition Counter:", counter)
137+
138+
print("\n4. Race Condition Fixed with Lock:")
139+
threads = [threading.Thread(target=thread_safe_increment) for _ in range(2)]
140+
[t.start() for t in threads]
141+
[t.join() for t in threads]
142+
print("✅ Safe Counter with Lock:", safe_counter)
143+
144+
print("\n5. Counting Thread:")
145+
count_thread = threading.Thread(target=count_numbers, args=("Counter",))
146+
count_thread.start()
147+
count_thread.join()
148+
149+
print("\n6. Multi-threaded Counter:")
150+
multi_threaded_counter()
151+
152+
print("\n7. Thread Join Demo:")
153+
show_join()
154+
155+
print("\n8. Daemon Thread (runs in background):")
156+
daemon = threading.Thread(target=background_logger, daemon=True)
157+
daemon.start()
158+
time.sleep(3) # Let daemon run briefly
159+
160+
print("\n9. Performance Comparison:")
161+
performance_compare()
162+
163+
print("\n10. Thread-safe Increment:")
164+
run_safe_threads()

0 commit comments

Comments
 (0)