Здесь нет тупиков, потому что программа main
не заблокирована. Он отправляет 3 значения на c
, что успешно, потому что есть 4 запущенных goroutines, получающих от него, и затем это заканчивается. И с этим ваше приложение также заканчивается, оно не ждет завершения других не-1003 * подпрограмм. См. Нет вывода из goroutine .
В результате тупиковой ситуации все goroutines должны быть заблокированы. Здесь дело обстоит иначе.
Это не ошибка, чтобы попытаться получить от канала, где нет никого (в настоящее время или когда-либо) готового к отправке. На самом деле это совершенно нормально. Это один из вариантов использования каналов: он выступает в качестве инструмента синхронизации, вы можете отправлять / получать, и операция будет блокироваться до тех пор, пока не будет готов другой конец.
В некоторых случаях блокируется даже выполнение программы для всего времени жизни приложения нормально, например, программа может ожидать ввода пользователя, такого как CTRL + BREAK , который пользователь никогда не может нажать, и приложение может нормально завершиться.
Так что это не считается ошибкой, и для них не выводятся сообщения об ошибках или предупреждения. Но если вам интересно, это легко реализовать. Просто добавьте отложенную функцию к вашему main()
, которая будет вызываться последней, прежде чем ваша main()
функция (и ваше приложение с ней) завершится. В этой строке выведите количество запущенных процедур:
func main() {
defer func() {
fmt.Println("Remaining goroutines:", runtime.NumGoroutine()-1) //-1 for main
}()
// your code
}
С этим дополнением вы получите:
received: 1
received: 2
received: 3
Remaining goroutines: 1
Если вы измените свой l oop, чтобы запустить 14 функций вместо 1 , output скажет, что осталось 11 подпрограмм.
Последнее примечание: поскольку в вашем приложении функция main()
не ожидает завершения других подпрограмм, они могут оставаться активными в момент вызова отложенных функций. , так что они могут или не могут быть включены в число оставшихся goroutines. Если вы будете использовать, например, sync.WaitGroup
, чтобы дождаться их окончания, то они точно не будут включены. См. Предотвращение завершения функции main () до завершения выполнения goroutines sh in Golang.