import concurrent.futures
import time
import os # To show process ID, useful for ProcessPoolExecutor
 
def simulate_io_task(url):
    """Simulates fetching data from a URL."""
    print(f"Fetching {url} (Thread: {time.thread_time_ns() % 1000000})") # Use thread_time_ns for thread ID
    delay = len(url) % 3 + 1 # Simulate varying network delays
    time.sleep(delay)
    print(f"Finished {url} in {delay} seconds.")
    return f"Content from {url} after {delay}s"
 
urls = [
    "http://example.com/page1",
    "http://example.com/page2",
    "http://example.com/page3",
    "http://example.com/page4",
    "http://example.com/page5",
]
 
print("--- Using ThreadPoolExecutor.map() ---")
# Use a ThreadPoolExecutor for I/O-bound tasks
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    # map returns an iterator that yields results in input order
    results_iterator = executor.map(simulate_io_task, urls)
 
    for result in results_iterator:
        print(f"ThreadPoolExecutor result: {result}")
 
print("All ThreadPoolExecutor tasks complete.")