package main import ( "fmt" "sync" "time" ) func worker(id int, done <-chan struct{}, wg *sync.WaitGroup) { defer wg.Done() fmt.Printf("Worker %d starting... ", id) for { select { case <-done: fmt.Printf("Worker %d received shutdown signal, exiting. ", id) return case <-time.After(500 * time.Millisecond): fmt.Printf("Worker %d still working... ", id) } } } func main() { var wg sync.WaitGroup done := make(chan struct{}) numWorkers := 3 for i := 1; i <= numWorkers; i++ { wg.Add(1) go worker(i, done, &wg) } fmt.Println("Main: Workers started. Running for 3 seconds...") time.Sleep(3 * time.Second) fmt.Println("Main: Sending shutdown signal to all workers...") close(done) // Closing the channel broadcasts to all listeners wg.Wait() fmt.Println("Main: All workers shut down.") }