Источник: Nuances of Programming
Горутина — это эффективный и легковесный механизм многопоточного выполнения, популярный среди разработчиков Go. С помощью семантики горутин программисты добиваются эффективного выполнения параллельных процессов в программе. Впрочем, следует помнить о подводных камнях, чтобы избежать незапланированных побочных эффектов.
Программа
Логика программы проста: есть набор функций определенного типа, который нужно перебрать и выполнить. Каждая из функций независима, поэтому удобно использовать индивидуальные горутины. Код имеет следующий вид:
“ConcurrentFunctions” — это функция с переменным количеством аргументов, которая принимает на вход любое число функций, перебирает и реализует их. Реализация каждой функции происходит за счёт отдельной горутины. Согласно логике, вывод должен был быть “I am function func1” и “I am function func2”, но это не так.
I am function func2
I am function func2
Ошибка
Загвоздка кроется в этой части кода:
Каждая итерация цикла создавала анонимную функцию замыкания с горутиной, использующей ту же переменную “fn”, что и родительский цикл. Горутины выполняются асинхронно, поэтому для каждой из них в момент использования актуальна переменная “fn”. В большинстве случаев внешний цикл завершался до реализации какой-либо горутины, поэтому “fn” указывает на “func2”. Таким образом, обе горутины замыкаются на func2.
Решение
Поскольку причиной ошибки стала переменная “fn”, проблему может решить изменение следующей секции кода:
Вместо обращения к переменной “fn” напрямую, механизм замыкания горутины принимает функцию в качестве параметра, при этом копируя её для каждой из итераций горутин.
С этим небольшим изменением выходные данные приняли следующий вид:
I am function func2
I am function func1
Читайте также:
Читайте нас в телеграмме и vk
Перевод статьи Pranay Singhal: A Goroutines Gotcha