Concurrent Task Orchestration with sync.WaitGroup
This challenge focuses on utilizing Go's sync.WaitGroup to manage and synchronize concurrent tasks. sync.WaitGroup is a powerful tool for waiting for a collection of goroutines to finish, ensuring your program doesn't exit prematurely. You'll implement a function that launches multiple goroutines, each performing a simulated task, and then waits for all of them to complete before proceeding.
Problem Description
You are tasked with creating a Go function called waitForTasks that takes an integer numTasks as input. This function should:
- Create a
sync.WaitGroup. - Launch
numTasksgoroutines. Each goroutine should:- Simulate a task by sleeping for a random duration between 100ms and 500ms (inclusive). Use
time.Sleepandtime.Duration(rand.Intn(401)) * time.Millisecond. You'll need to import themath/randandtimepackages. Seed the random number generator once at the beginning of the function. - Increment the
WaitGroupcounter before starting the sleep. - Decrement the
WaitGroupcounter after completing the sleep.
- Simulate a task by sleeping for a random duration between 100ms and 500ms (inclusive). Use
- Call
wg.Wait()to block the main goroutine until all launched goroutines have finished. - After
wg.Wait()returns, print a message indicating that all tasks have completed.
Key Requirements:
- Correctly use
sync.WaitGroupto synchronize the goroutines. - Simulate tasks with varying durations using
time.Sleep. - Ensure the main goroutine waits for all tasks to finish before exiting.
- Seed the random number generator to ensure different sleep durations each run.
Expected Behavior:
The program should launch numTasks goroutines, each sleeping for a random duration. The main goroutine should wait for all of these goroutines to finish before printing the completion message. The order in which the goroutines complete is not important.
Edge Cases to Consider:
numTasksis 0: No goroutines should be launched, and the completion message should be printed immediately.numTasksis a large number: The program should still function correctly and wait for all goroutines to finish.
Examples
Example 1:
Input: numTasks = 3
Output: (After a random delay between 300ms and 1.5s) "All tasks completed!"
Explanation: Three goroutines are launched, each sleeping for a random duration. The main goroutine waits for all three to finish before printing the message.
Example 2:
Input: numTasks = 0
Output: "All tasks completed!"
Explanation: No goroutines are launched. The WaitGroup counter remains 0, and wg.Wait() returns immediately. The completion message is printed.
Example 3:
Input: numTasks = 5
Output: (After a random delay between 500ms and 2.5s) "All tasks completed!"
Explanation: Five goroutines are launched, each sleeping for a random duration. The main goroutine waits for all five to finish before printing the message.
Constraints
numTaskswill be a non-negative integer.- The sleep duration within each goroutine will be between 100ms and 500ms (inclusive).
- The program should complete within a reasonable time (e.g., 5 seconds) even for a large number of tasks (e.g., 100).
- The random number generator must be seeded only once.
Notes
- Remember to import the necessary packages:
math/randandtime. - The
sync.WaitGroupcounter must be incremented before the goroutine starts its work and decremented after it finishes. Incorrect ordering can lead to premature termination. - Consider using a
defer wg.Done()to ensure theWaitGroupcounter is decremented even if the goroutine panics. While not strictly required for this problem, it's good practice. - Focus on the correct usage of
sync.WaitGroupto synchronize the goroutines. The specific sleep duration is less important than the synchronization logic.