28 ноя 2025 · 12:00    
{"document": [{"text": [{"type": "string", "attributes": {}, "string": "Горутины — одна из самых мощных и отличительных особенностей языка Go. Это легковесные потоки выполнения, которые позволяют писать высокопроизводительные параллельные программы. В этой статье мы глубоко изучим, "}, {"type": "string", "attributes": {"href": "https://dzen.ru/a/aRG9RKQ9n3tywOBd"}, "string": "что"}, {"type": "string", "attributes": {}, "string": " такое горутины, как они работают и как правильно их использовать в реальных приложениях."}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Что такое горутины"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Горутины — это функции или методы, которые выполняются конкурентно с другими горутинами. Они не являются потоками операционной системы в традиционном понимании, а представляют собой абстракцию над потоками, управляемую рантаймом Go."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Основные характеристики горутин"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Легковесные — потребляют всего 2-8 КБ памяти каждая"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "Быстрый запуск — создание в тысячи раз быстрее потоков ОС"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "Автоматическое управление — планировщик Go распределяет их по потокам ОС"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "Встроенная в язык — не требуют внешних библиотек"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "Создание и запуск горутин"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Для запуска горутины используется ключевое слово go перед вызовом функции:"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Базовый пример"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "package main\n\nimport (\n «fmt» \n «time» \n) \n\nfunc sayHello () {\n fmt. Println («Привет из горутины!») \n}\n\nfunc main () {\n // Запуск горутины\n go sayHello () \n \n // Даем время горутине выполниться\n time. Sleep (100 * time. Millisecond) \n fmt. Println («Основная функция завершена») \n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Запуск анонимной функции"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "func main () {\n // Запуск анонимной функции как горутины\n go func (name string) {\n fmt. Printf («Привет, %s! \\n», name) \n } («Анна») \n \n time. Sleep (time. Millisecond * 50) \n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {}, "string": "Планировщик Go (Scheduler)"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Планировщик Go — это интеллектуальный компонент рантайма, который управляет выполнением горутин. Он использует модель M: N, где M горутин выполняются на N потоках ОС."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Компоненты планировщика"}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "G (Goroutine)"}, {"type": "string", "attributes": {}, "string": " — представляет саму горутину"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "M (Machine)"}, {"type": "string", "attributes": {}, "string": " — поток операционной системы"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "P (Processor)"}, {"type": "string", "attributes": {}, "string": " — логический процессор, который выполняет горутины"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Принцип работы"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "func demonstrateScheduler () {\n for i: = 0; i < 5; i++ {\n go func (num int) {\n fmt. Printf («Горутина %d выполняется\\n», num) \n } (i) \n }\n \n time. Sleep (time. Second) \n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {}, "string": "Каналы (Channels) — коммуникация между горутинами"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Каналы — это типизированные конвейеры для связи и синхронизации горутин. Они обеспечивают безопасный обмен данными."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Создание и использование каналов"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "func basicChannelExample () {\n // Создание небуферизованного канала\n ch: = make (chan string) \n \n go func () {\n // Отправка данных в канал\n ch <- «Сообщение из горутины» \n } () \n \n // Получение данных из канала\n message: = <-ch\n fmt. Println (message) \n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Буферизованные каналы"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "func bufferedChannelExample () {\n // Создание канала с буфером на 3 элемента\n ch: = make (chan int, 3) \n \n go func () {\n for i: = 0; i < 5; i++ {\n ch <- i\n fmt. Printf («Отправлено: %d\\n», i) \n }\n close (ch) \n } () \n \n // Чтение из канала\n for value: = range ch {\n fmt. Printf («Получено: %d\\n», value) \n }\n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {}, "string": "Синхронизация горутин"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Правильная синхронизация критически важна для корректной работы конкурентных программ."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "WaitGroup для ожидания завершения"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "import «sync» \n\nfunc waitGroupExample () {\n var wg sync. WaitGroup\n \n for i: = 0; i < 3; i++ {\n wg. Add (1) // Увеличиваем счетчик\n go func (id int) {\n defer wg. Done () // Уменьшаем счетчик при завершении\n fmt. Printf («Горутина %d работает\\n», id) \n time. Sleep (time. Second) \n } (i) \n }\n \n wg. Wait () // Ждем завершения всех горутин\n fmt. Println («Все горутины завершены») \n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Mutex для защиты общих данных"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "type SafeCounter struct {\n mu sync. Mutex\n value int\n}\n\nfunc (c *SafeCounter) Increment () {\n c. mu. Lock () \n defer c. mu. Unlock () \n c. value++\n}\n\nfunc (c *SafeCounter) Value () int {\n c. mu. Lock () \n defer c. mu. Unlock () \n return c. value\n}\n\nfunc mutexExample () {\n counter: = SafeCounter{}\n \n var wg sync. WaitGroup\n for i: = 0; i < 1000; i++ {\n wg. Add (1) \n go func () {\n defer wg. Done () \n counter. Increment () \n } () \n }\n \n wg. Wait () \n fmt. Printf («Итоговое значение: %d\\n», counter. Value ())\n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {}, "string": "Паттерны работы с горутинами"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Рассмотрим распространенные паттерны использования горутин в реальных приложениях."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Worker Pool (Пул воркеров)"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "func workerPoolExample () {\n jobs: = make (chan int, 100) \n results: = make (chan int, 100) \n \n // Создаем воркеры\n for w: = 1; w <= 3; w++ {\n go worker (w, jobs, results) \n }\n \n // Отправляем задания\n for j: = 1; j <= 9; j++ {\n jobs <- j\n }\n close (jobs) \n \n // Собираем результаты\n for a: = 1; a <= 9; a++ {\n fmt. Printf («Результат: %d\\n», <-results) \n }\n}\n\nfunc worker (id int, jobs <-chan int, results chan<- int) {\n for job: = range jobs {\n fmt. Printf («Воркер %d обрабатывает задание %d\\n», id, job) \n time. Sleep (time. Second) // Имитация работы\n results <- job * 2\n }\n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Fan-out, Fan-in"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "func fanOutFanInExample () {\n in: = generateNumbers (10) \n \n // Fan-out: распределяем работу между несколькими горутинами\n c1: = square (in) \n c2: = square (in) \n c3: = square (in) \n \n // Fan-in: объединяем результаты\n for result: = range merge (c1, c2, c3) {\n fmt. Printf («Результат: %d\\n», result) \n }\n}\n\nfunc generateNumbers (n int) <-chan int {\n out: = make (chan int) \n go func () {\n for i: = 0; i < n; i++ {\n out <- i\n }\n close (out) \n } () \n return out\n}\n\nfunc square (in <-chan int) <-chan int {\n out: = make (chan int) \n go func () {\n for n: = range in {\n out <- n * n\n }\n close (out) \n } () \n return out\n}\n\nfunc merge (channels... <-chan int) <-chan int {\n var wg sync. WaitGroup\n out: = make (chan int) \n \n output: = func (c <-chan int) {\n defer wg. Done () \n for n: = range c {\n out <- n\n }\n }\n \n wg. Add (len (channels))\n for _, c: = range channels {\n go output (c) \n }\n \n go func () {\n wg. Wait () \n close (out) \n } () \n \n return out\n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {}, "string": "Ошибки и их обработка в горутинах"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Обработка ошибок в конкурентных программах требует особого подхода."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Канал для ошибок"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "func processWithErrors () error {\n jobs: = []string{ «task1», «task2», «error_task», «task4» }\n \n errCh: = make (chan error, len (jobs))\n var wg sync. WaitGroup\n \n for _, job: = range jobs {\n wg. Add (1) \n go func (j string) {\n defer wg. Done () \n if j == «error_task» {\n errCh <- fmt. Errorf («ошибка в задаче: %s», j) \n return\n }\n fmt. Printf («Обработано: %s\\n», j) \n } (job) \n }\n \n wg. Wait () \n close (errCh) \n \n // Проверяем ошибки\n for err: = range errCh {\n if err! = nil {\n return err\n }\n }\n \n return nil\n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {}, "string": "Производительность и оптимизация"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Правильное использование горутин может значительно повысить производительность приложений."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Избегайте утечек горутин"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "func avoidGoroutineLeaks () {\n done: = make (chan bool) \n \n go func () {\n for {\n select {\n case <-done: \n fmt. Println («Горутина завершена») \n return\n default: \n // Полезная работа\n time. Sleep (time. Millisecond * 100) \n }\n }\n } () \n \n // Даем горутине поработать\n time. Sleep (time. Second) \n \n // Сигнал завершения\n close (done) \n time. Sleep (time. Millisecond * 100) \n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Использование context для отмены операций"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "func contextExample () {\n ctx, cancel: = context. WithTimeout (context. Background (), 2*time. Second) \n defer cancel () \n \n go func () {\n for {\n select {\n case <-ctx. Done (): \n fmt. Println («Операция отменена:», ctx. Err ())\n return\n default: \n // Имитация работы\n time. Sleep (time. Millisecond * 500) \n fmt. Println («Работаем...») \n }\n }\n } () \n \n time. Sleep (3 * time. Second) \n}\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {}, "string": "Лучшие практики работы с горутинами"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Следование лучшим практикам помогает создавать надежные и эффективные конкурентные программы."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Принципы проектирования"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Используйте принцип «Не общайтесь через общую память, общайтесь через коммуникацию» "}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "Всегда закрывайте каналы, когда больше не нужно писать в них"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "Используйте буферизованные каналы для уменьшения блокировок"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "Ограничивайте количество одновременно работающих горутин"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Распространенные антипаттерны"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "Запуск горутин без контроля их жизненного цикла"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "Использование глобальных переменных без синхронизации"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "Создание слишком большого количества горутин"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "Игнорирование обработки ошибок в горутинах"}], "attributes": ["bulletList", "bullet"]}, {"text": [{"type": "string", "attributes": {}, "string": "«Горутины — это не потоки. Горутины — это абстракция, которая позволяет писать конкурентный код так, как будто он последовательный, в то время как планировщик заботится о параллельном выполнении.» — Роб Пайк"}], "attributes": ["quote"]}, {"text": [{"type": "string", "attributes": {}, "string": "Отладка и мониторинг горутин"}], "attributes": ["heading1"]}, {"text": [{"type": "string", "attributes": {}, "string": "Инструменты для анализа работы горутин в реальном времени."}], "attributes": []}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Использование pprof"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "import _ «net/http/pprof» \n\nfunc startProfiling () {\n go func () {\n log. Println (http. ListenAndServe («localhost: 6060», nil))\n } () \n}\n\n// Анализ горутин через pprof: \n// go tool pprof http: //localhost: 6060/debug/pprof/goroutine\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {"bold": true}, "string": "Трассировка выполнения"}], "attributes": []}, {"text": [{"type": "string", "attributes": {}, "string": "func traceExample () {\n trace. Start (os. Stdout) \n defer trace. Stop () \n \n // Код с горутинами\n var wg sync. WaitGroup\n for i: = 0; i < 5; i++ {\n wg. Add (1) \n go func (id int) {\n defer wg. Done () \n time. Sleep (time. Millisecond * 100) \n } (i) \n }\n wg. Wait () \n}\n\n// Анализ: go run main. go > trace. out\n// go tool trace trace. out\n"}], "attributes": ["code"]}, {"text": [{"type": "string", "attributes": {}, "string": "Горутины — это фундаментальная концепция языка "}, {"type": "string", "attributes": {"href": "https://dzen.ru/a/aRG9RKQ9n3tywOBd"}, "string": "Go"}, {"type": "string", "attributes": {}, "string": ", которая делает его исключительно мощным для создания высокопроизводительных конкурентных приложений. Понимание их работы и правильное использование открывает возможности для создания систем, эффективно использующих ресурсы процессора и способных обрабатывать тысячи одновременных операций."}], "attributes": []}], "selectedRange": [178, 303]}
Комментарии 0