在下面的代码中:
package main
import (
"fmt"
"math/rand"
"time"
)
// waitForTask: You are a manager and you hire a new employee. Your new
// employee doesn't know immediately what they are expected to do and waits for
// you to tell them what to do. You prepare the work and send it to them. The
// amount of time they wait is unknown because you need a guarantee that the
// work your sending is received by the employee.
func waitForTask() {
ch := make(chan string)
// var wg sync.WaitGroup
// wg.Add(1)
go func() { // new Employee
p := <-ch // Channel receive will happen before send(from main)
fmt.Println("employee : recv'd signal :", p) // do the work
// wg.Done()
}()
time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond) // prepare the work
ch <- "paper" // and send it to employee
fmt.Println("manager : sent signal")
// wg.Wait() // Wait for the work to complete by employee
fmt.Println("-------------------------------------------------------------")
}
func main() {
waitForTask()
}
channel receive(p := <-ch
) happens before channel send(is held at ch <- "paper"
in main
), because this is unbuffered channel
在等待任务模式中,
Does main()
(manager) need to wait for the work to complete by employee, using sync.WaitGroup
?
要么
Does main()
need to just ensure that the work is sent to employee?
根据Go内存模型:
So in the main goroutine when channel send completes, it is certain that the receive happened. It doesn't mean that
p
variable is set to the value sent yet though. And, in the nested goroutine when receive is completed, it is certain that the sending in main goroutine is completed. It doesn't mean the next line started execution.If main does not wait for the work to complete, the program will probably end before the worker can finish its work. So, you have to wait for the worker to finish, either by using
WorkGroup
or some other synchronization mechanism.