Thread creation and management in Operating Systems - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
When we create and manage threads in an operating system, it is important to understand how the time taken grows as we increase the number of threads.
We want to know how the cost of starting and handling threads changes when we add more threads.
Analyze the time complexity of the following thread creation and management code snippet.
for (int i = 0; i < n; i++) {
pthread_create(&thread[i], NULL, thread_function, NULL);
}
for (int i = 0; i < n; i++) {
pthread_join(thread[i], NULL);
}
This code creates n threads and then waits for each to finish.
- Primary operation: Creating and joining each thread in a loop.
- How many times: Each loop runs exactly
ntimes, once per thread.
As the number of threads n increases, the total time to create and join all threads grows proportionally.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 operations (10 creates + 10 joins) |
| 100 | About 200 operations |
| 1000 | About 2000 operations |
Pattern observation: The total operations increase linearly as the number of threads increases.
Time Complexity: O(n)
This means the time to create and manage threads grows directly in proportion to the number of threads.
[X] Wrong: "Creating multiple threads happens instantly and does not add up with more threads."
[OK] Correct: Each thread creation and join takes some time, so more threads mean more total time spent.
Understanding how thread creation time grows helps you design programs that use threads efficiently and avoid unexpected delays.
"What if threads were created recursively instead of in a loop? How would the time complexity change?"
Practice
Solution
Step 1: Understand what threads do
Threads let a program split work into parts that run at the same time.Step 2: Identify the main benefit
This helps the program do many tasks faster and be more responsive.Final Answer:
To allow a program to perform multiple tasks at the same time -> Option BQuick Check:
Threads = multitasking [OK]
- Thinking threads increase memory size
- Believing threads slow down programs
- Confusing threads with file handling
Solution
Step 1: Understand thread starting methods
Threads usually start by calling a special method likestart()which runs the thread's code in parallel.Step 2: Identify correct usage
Callingrun()directly runs code in the current thread, not a new one.stop()anddelete()are not used to start threads.Final Answer:
Define the thread function and callstart()on the thread object -> Option AQuick Check:
Use start() to launch threads [OK]
- Calling run() instead of start()
- Trying to stop a thread to start it
- Using delete() to manage threads
thread = createThread(taskFunction) thread.start() thread.join()
What does
thread.join() do?Solution
Step 1: Understand thread.join()
Thejoin()method pauses the current program until the thread finishes its task.Step 2: Identify the effect of join()
This ensures the program waits for the thread to complete before moving on.Final Answer:
Waits for the thread to finish before continuing -> Option AQuick Check:
join() = wait for thread end [OK]
- Thinking join() starts the thread
- Confusing join() with stopping the thread
- Believing join() creates a new thread
thread = createThread(taskFunction) thread.run()
Choose the best explanation.
Solution
Step 1: Understand difference between run() and start()
Callingrun()directly executes the task in the current thread, not a new thread.Step 2: Identify the problem
This means no new thread is created, so the program does not run tasks concurrently.Final Answer:
Calling run() runs the task in the current thread, not a new thread -> Option DQuick Check:
run() = no new thread [OK]
- Thinking run() starts a new thread
- Assuming thread runs twice
- Believing thread never executes
Solution
Step 1: Understand thread starting and joining
Starting each thread runs tasks concurrently. Callingjoin()waits for each thread to finish.Step 2: Identify correct management
Starting all threads first allows parallel work, then joining ensures the main program waits for all to complete.Final Answer:
Start each thread and call join() on each one after starting all -> Option CQuick Check:
Start all, then join all = proper thread management [OK]
- Calling run() instead of start()
- Not joining threads, causing premature exit
- Starting only one thread and ignoring others
