package main import ( "fmt" "time" ) // Request represents a task to be processed, including a channel for the response. type Request struct { ID int Payload string ReplyCh chan<- string // Dedicated channel for the response } // Worker processes requests and sends responses back. func worker(requests <-chan Request) { for req := range requests { fmt.Printf("Worker: Processing request ID %d: %s ", req.ID, req.Payload) time.Sleep(50 * time.Millisecond) // Simulate work response := fmt.Sprintf("Response for ID %d: Processed '%s'", req.ID, req.Payload) req.ReplyCh <- response // Send response back on the dedicated channel } } func main() { requests := make(chan Request) go worker(requests) // Start a single worker numRequests := 3 // Create a slice to hold reply channels for each request replyChannels := make([]chan string, numRequests) fmt.Println("Main: Sending requests...") for i := 0; i < numRequests; i++ { replyCh := make(chan string) // Create a new reply channel for each request replyChannels[i] = replyCh req := Request{ ID: i + 1, Payload: fmt.Sprintf("Data-%d", i+1), ReplyCh: replyCh, } requests <- req // Send the request to the worker } fmt.Println("Main: Waiting for responses...") for i := 0; i < numRequests; i++ { response := <-replyChannels[i] // Block until response is received for this specific request fmt.Printf("Main: Received %s ", response) close(replyChannels[i]) // Close the reply channel after use } close(requests) // Close the requests channel to signal worker to exit // Give worker a moment to process before main potentially exits time.Sleep(100 * time.Millisecond) fmt.Println("Main: All requests processed and responses received.") }