Синтаксис и семантика Goroutines в Go недурна. Те же сопрограммы.
С явной точкой переключения.
Однако их исполняет несколько потоков.
Т.е. вместо того, чтобы декларировать, что все горутины по-умолчанию неконкурентны (т.е. все объекты общего назначения и проч. пишутся без необходимости думать о конкурентности), и разрешить отправлять горутину на конкурентное исполнение только явно (когда это изолированно что-то считающая или интерфейсная с внешним миром горутина - в реализации библиотеки-биндинга где-то), был принят подход конкурентного исполнения горутин.

Ну и... "довели бабы (треды) да кабаки (разделяемые объекты) до цугундера (гонок)".

https://habrahabr.ru/post/333346/

> -- Цитата:
> Другая проблема, которую мы могли бы хотеть решить после выхода Go 1 был факт того, что горутины и разделённая (shared) память позволяли слишком легко создать ситуацию гонки (races) в Go программах, приводящих к падениям и прочим проблемам в работе. Решение, основанное на изменении языка, могло бы заключаться в том, чтобы найти какой-то способ гарантировать отсутствие ситуаций гонки, сделать так, чтобы такие программы не компилировались, например. Как это сделать для такого языка, как Go пока что остается открытым вопросом в мире языков программирования. Вместо этого мы добавили базовый инструмент, который очень просто использовать — этот инструмент, детектор гонок (race detector) стал неотъемлемой частью опыта работы с Go. В этом случае наилучшим решением оказалось изменение в runtime и в инструментарии, а не изменение языка.