goroute with select Does Not Terminate Without fmt.Print()
In the Go Tour exercise #71, a goroute with a select statement executes continuously unless a fmt.Print() statement is added in the default case. This behavior arises due to select's altered operation when a default statement is present.
Without a default, select blocks until a message is received on any of the channels being monitored. By adding a default, select executes the default branch whenever none of the channels have messages.
In the original code, the default statement creates an infinite loop:
for { select { case todo := <-toDoList: ... case <-doneCrawling: ... default: if os.Args[1] == "ok" { fmt.Print("") } if crawling == 0 { goto END } } }
Without the fmt.Print() within the default, the scheduler cannot schedule other goroutines, resulting in a deadlock. Adding fmt.Print() allows the scheduler to continue its normal function, enabling the completion of the goroutine.
Modifying the code to use a non-blocking select resolves the issue:
for { select { case todo := <-toDoList: ... case <-doneCrawling: ... } if crawling == 0 { break } }
Alternatively, the original code can be made to work by setting GOMAXPROCS=2, indicating an issue with an overloaded scheduler.
The above is the detailed content of Why Does a Go `select` Statement Need `fmt.Print()` to Terminate in a Specific Goroutine?. For more information, please follow other related articles on the PHP Chinese website!