С точки зрения времени выполнения вы получаете тупик, потому что все подпрограммы пытаются отправить на канал, и нет никакой процедуры, ожидающей получения чего-либо.
Но Почему это происходит? Я расскажу вам историю, поскольку мне нравится визуализировать, что делают мои подпрограммы, когда я сталкиваюсь с тупиком.
У вас есть два игрока (подпрограммы) и один мяч (true
значение). Каждый игрок ждет мяч, и как только он их получит, он передает его другому игроку (через канал). Это то, что делают ваши две процедуры, и это действительно вызовет бесконечный цикл.
Проблема заключается в третьем игроке, представленном в вашем основном цикле. Он прячется за вторым игроком, и как только он видит, что у первого игрока есть пустые руки, он бросает на него еще один мяч. Таким образом, мы в итоге с игроками, держащими мяч, не могли передать его другому игроку, потому что у другого есть (первый) мяч в его руках. Скрытый, злой игрок также пытается пройти еще один мяч. Все путаются, потому что есть три мяча, три игрока и пустые руки.
Другими словами, вы ввели третьего игрока, который нарушает игру. Он должен быть арбитром, пропустившим первый мяч в начале игры, наблюдая за ним, но прекратите производство мячей! Это означает, что вместо того, чтобы иметь петлю в вашей основной процедуре, должно быть просто chan1 <- true
(и некоторое условие ждать, поэтому мы не выходим из программы).
Если вы включили ведение журнала в цикле основной процедуры, вы увидите, что тупик встречается всегда на третьей итерации. Количество выполняемых других подпрограмм зависит от планировщика. Возвращение истории: первая итерация - это начало первого шара; следующая итерация - загадочный второй мяч, но это можно обработать. Третья итерация - это тупик - это воплощает в жизнь третий шар, который никто не может решить.
Это полезно и имеет смысл. Поэтому я собираюсь предположить, что theres никоим образом канал не может иметь более чем одну добавленную стоимость, поэтому это означает, что Go уже считал goroutine «спящим», а не просто заблокированным каналом. Как/почему он будет спать? –
Он заблокирован операциями с каналами, что не может разблокировать. Среда выполнения обнаруживает, что все goroutines находятся в заблокированном состоянии, поэтому нет события, которое могло бы разблокировать любой из них. – HectorJ