Python中创建Thread后调用join()相比普通阻塞进程有何优势?
Great question! Let's break down your examples and the broader use cases clearly.
First: Your Exact Examples Are Identical in Behavior
In the code snippets you shared, there's no practical difference in how the program runs.
When you call t.join() right after starting the thread, you're forcing the main thread to wait for the child thread to finish before proceeding. So both code paths:
- Block for 5 seconds
- Print "start..."
- Print "end..."
The thread version doesn't give you any advantage here—it just adds a tiny bit of thread management overhead for no benefit.
When Thread + join Does Offer Advantages
The value of using threads with join comes when you need parallelism or flexibility that direct calls can't provide:
1. Parallelizing Multiple IO-Bound Tasks
If you have multiple tasks that spend most of their time waiting (like network requests, file IO, or time.sleep), threads let you run them in parallel instead of sequentially. This cuts down your total runtime drastically.
For example:
import threading import time def wait(seconds): time.sleep(seconds) print(f"Done waiting {seconds}s") # Threaded approach (total runtime ~5s) t1 = threading.Thread(target=wait, args=(3,)) t2 = threading.Thread(target=wait, args=(5,)) t1.start() t2.start() t1.join() t2.join() print("All done!") # Sequential approach (total runtime ~8s) wait(3) wait(5) print("All done!")
Here, the threaded version finishes in ~5 seconds (the length of the longest task), while the sequential one takes 8 seconds. This is a huge win for IO-bound work.
2. Doing Work While Waiting for a Task
You can start a thread, let it run in the background, and do other work in the main thread before calling join to wait for it to finish. This is impossible with a direct blocking call.
Example:
import threading import time def long_running_io_task(): time.sleep(5) print("IO task finished!") t = threading.Thread(target=long_running_io_task) t.start() # Main thread can handle other work here instead of blocking print("Main thread is processing some quick calculations...") time.sleep(2) print("Main thread done with its work—now waiting for the IO task.") t.join() print("All tasks complete!")
When Direct Function Calls Are Better
Stick to direct calls when:
- Your task is CPU-bound: Python's Global Interpreter Lock (GIL) prevents threads from running CPU-heavy code in parallel. Threads will just add overhead here—use multiprocessing instead if you need parallelism, or stick to sequential calls.
- You need strict serial execution: If your next line of code depends entirely on the previous function finishing (no room for parallel work), direct calls are simpler and avoid unnecessary thread management.
- Simplicity is key: Threads add complexity (like potential race conditions if shared state is involved). If you don't need parallelism, keep your code straightforward with direct calls.
Final Takeaway
Your original examples are functionally identical—neither is better than the other. But when you need to run multiple IO-bound tasks in parallel, or want to do work while waiting for a long task, threads with join become extremely useful. For serial, CPU-bound, or simple tasks, direct calls are the way to go.
内容的提问来源于stack exchange,提问作者akmalmzamri

