import concurrent.futuresimport timeimport os # To show process ID, useful for ProcessPoolExecutordef 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 taskswith 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.")