Создать подпрограмму go просто, так как процедура go легковесна, мы можем создать тысячи подпрограмм go для выполнения задач. Но каждая процедура имеет свою стоимость - затраты на потребление ресурсов, таких как использование памяти или ЦП.
Какими бы простыми в использовании ни были подпрограммы go, важно также управлять ими. Нам нужно убедиться, что процедуры go должны освобождать вычислительные ресурсы после выполнения поставленных задач. В большинстве случаев мы используем процедуры go для одновременного выполнения нескольких задач, но если мы оставим go-рутину зависшей, это приведет к высокому потреблению вычислительных ресурсов в долгосрочной перспективе.
Проблема потребления ресурсов и невыполнения их после завершения приведет к уменьшению количества доступных ресурсов для запуска других процессов. Это приведет к постоянному зависанию системы и резкой загрузке процессора. Код, который выполнялся в 10 раз быстрее после использования подпрограмм go, начнет работать так же медленно, как в 100 раз по сравнению с предыдущим кодом. Иногда единственный способ решить эту проблему - выключить компьютер.
Один из способов - назначить ограниченный ЦП нашему коду golang с помощью пакета времени выполнения и выделить ограниченные ресурсы, но это не решит проблему. Мы должны внедрить постоянное решение этой проблемы. Назначение подпрограммам объема работы и их закрытие после завершения назначенной задачи - лучший способ справиться с ней.
Давайте рассмотрим несколько примеров рутинной утечки информации.
Вышеупомянутый код будет работать, как ожидалось, без ошибок, но процедура go будет продолжать работать из-за того, что цикл for никогда не заканчивается, что вызывает утечку, поскольку нет сигнала или способа остановить его в случае ошибки.
Давайте посмотрим на другой пример утечки подпрограмм go при запуске нескольких подпрограмм go, которые вместе пишут в один и тот же канал.
Поскольку мы используем для выбора вариант по умолчанию, тупиковая ситуация в рутине не возникает. Несмотря на то, что программа запускается несколько раз, есть вероятность, что значения, переданные в канал, никогда не будут получены, например, в случае запросов REST api.
Существует сторонний пакет, созданный, чтобы выяснить, есть ли утечка внутри программы, запустив тесты. Пакет с открытым исходным кодом используется в качестве стандартного течеискателя https://github.com/uber-go/goleak. Я использовал тот же пакет, чтобы узнать, есть ли утечки в запущенных в программе процедурах go.
После создания тестового файла для программы, упомянутой во втором примере. Мы можем запустить тестовый файл, используя go test
. Он вернет номер процедуры go, выполнение которой не удастся. Затем нам нужно проверить место возникновения обычной утечки и устранить ее.
Чтобы устранить указанную выше утечку, мы должны убедиться, что все значения, отправленные по каналу, должны быть получены. Другой вариант - не отправлять значения по каналу, который не может быть получен.
В приведенном выше случае я отправил сигнал для остановки цикла через определенный период времени, чтобы убедиться, что не будет утечки. Могут быть и другие способы решения этой проблемы, а именно. получать все значения, отправленные по каналу, или не выходить из режима ожидания.
Вывод: - Использовать подпрограммы go несложно, но управлять ими важно, чтобы убедиться, что наше программное обеспечение будет работать эффективно в долгосрочной перспективе. Если не обработать должным образом, это приведет к блокировке процесса и потреблению больших ресурсов процессора и памяти для выполнения небольшого фрагмента кода. Следите за обновлениями….