Проблема в ответе на ваш вопрос заключается в том, что, похоже, никто не понимает, в чем заключается ваша проблема. Я вижу, вы постоянно спрашиваете примерно об одном и том же, хотя никакого прогресса достигнуто не было. Там нет никакого оскорбления, говоря это. Это попытка помочь вам с помощью предложения переформулировать вашу проблему так, чтобы это было понятно другим. Как возможный приятный побочный эффект, некоторые проблемы решаются сами, а другие объясняются понятным образом. Я испытал это много раз сам.
Еще одна подсказка может заключаться в подозрительной смеси явной синхронизации и канала связи. Это не значит, что дизайн обязательно сломан. Это просто не происходит в типичном / простом случае. Еще раз, ваша проблема может быть нетипичной / нетривиальной.
Возможно, возможно каким-то образом изменить вашу проблему, используя только каналы. На самом деле я считаю, что любая проблема, связанная с явной синхронизацией (в Go), может быть закодирована при использовании только каналов. Тем не менее, это правда, некоторые проблемы пишутся с явной синхронизацией очень легко. Канальная связь, как бы она ни была дешева, не такая дешевая, как большинство примитивов синхронизации. Но об этом можно будет позаботиться позже, когда код заработает. Если «шаблон» для некоторых, скажем, sync.Mutex будет заметно появляться в коде, то должна быть возможность переключиться на него и сделать это гораздо проще, когда код уже работает и, как мы надеемся, имеет тесты для отслеживания ваших шагов при внесении корректировок .
Попытайтесь думать о своих горутинах как о независимо действующих агентах, которые:
- Исключительно владеют данными, полученными с канала. Язык будет
не применять это, вы должны использовать собственную дисциплину.
- Больше не трогайте данные, которые они отправили на канал. Это следует из первого правила, но достаточно важно, чтобы быть явным.
- Взаимодействие с другими агентами (программами) по типам данных, которые инкапсулируют целую единицу рабочего процесса / вычисления. Это устраняет, например, Ваша предыдущая борьба с получением правильного количества сообщений на канале до того, как «юнит» будет завершен.
- Для каждого канала, который они используют, должно быть абсолютно ясно до , если канал должен быть небуферизован, должен быть буферизован для фиксированного числа элементов или если он не связан.
- Не нужно думать (знать) о том, что делают другие агенты, прежде чем получать от них сообщение, если это необходимо для того, чтобы агент выполнял свою собственную задачу - часть общей картины.
Использование даже такого количества эмпирических правил, как мы надеемся, приведет к созданию кода, о котором легче думать, и который обычно не требует какой-либо другой синхронизации. (Я намеренно игнорирую проблемы производительности критически важных приложений.)