Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Что такое горутины?
- Горутины являются ключевой особенностью языка Go.
- Они представляют собой легковесные потоки выполнения
- Горутины позволяют параллельно выполнять несколько задач в одной программе
- Преимущества горутин
- ---------------------
- Эффективное использование ресурсов: горутины обладают низким потреблением
- памяти и быстрым запуском.
- Простая синхронизация: использование каналов и синхронизаторов позволяет
- безопасно обмениваться данными между горутинами.
- Удобство работы с параллельными задачами: горутины упрощают разработку
- параллельных алгоритмов.
- Создание горутин
- ----------------
- Горутины создаются с помощью ключевого слова до,
- после которого следует вызов функции
- Пример создания горутины: go myFunction()
- func myFunction() {
- fmt.PrintLn("Выполнение в горутине")
- time.Sleep(time.Second) // Имитация работы горутины
- fmt.PrintLn("Горутина выполнена")
- }
- func main() {
- fmt.Println("Старт основной горутины")
- go myFunction() // Создание и запуск горутины
- fmt.PrintLn("Основная горутина продолжает работу")
- // Ожидание завершения выполнения горутины
- time.Sleep(2 * time.Second)
- fmt.PrintLn("Выполнение программы завершено")
- }
- ===================================================================================
- Каналы для обмена данными
- --------------------------
- Каналы предоставляют способ безопасного обмена данными между горутинами
- Они могут быть использованы для передачи значений от одной горутины к другой
- Пример создания канала: ch := make(chan int)
- func main() {
- // Создание канала типа int
- ch := make(chan int)
- // Горутина, которая отправляет значения в канал
- go func() {
- for t := 1; i <= 5; i++ {
- ch <- i // Отправка значения в канал
- }
- close(ch) // Закрытие канала
- }()//сразу запустится
- // Чтение значений из канала
- for num := range ch {
- fmt.Println(num) // Вывод значения из канала
- }
- }
- ==================================================================================
- Синхронизация с помощью WaitGroup
- ----------------------------------
- WaitGroup предоставляет механизм синхронизации выполнения горутин
- Он гарантирует, что все горутины завершат свою работу, прежде чем
- программа завершится.
- Пример использования WaitGroup: var wg sync.WaitGroup
- func worker(id int, wg *sync.WaitGroup) {
- defer wg.Done() // Указываем, что горутина завершила свою работу
- fmt.Printf("Горутина %d завершила свою работу\п", id)
- }
- func main() {
- var wg sync.WaitGroup // Создание WaitGroup
- for i := 1; i <= 3; i++ {
- wg.Add(l) // Увеличение счетчика горутин в WaitGroup
- go worker(i, &wg) // Запуск горутин
- }
- wg.Wait() // Ожидание завершения всех горутин
- fmt.Println("Все горутины завершили работу")
- }
- ===========================================================================
- В Go оператор select используется для работы с несколькими каналами одновременно.
- Он позволяет горутине ожидать операций на нескольких каналах и реагировать на тот
- канал, который первым станет готов к отправке или получению данных. Это ключевой
- инструмент для организации конкурентных (параллельных) программ и координации
- работы между горутинами.
- Как работает select
- select блокируется и ждёт, пока хотя бы одна из операций над каналами в его
- кейсах станет возможной.
- Если готово несколько каналов одновременно, выбирается случайный кейс.
- Если ни один канал не готов, select блокируется до появления возможности
- выполнить хотя бы одну операцию.
- Можно добавить опциональный кейс default - он выполнится, если ни один канал
- не готов, и select не будет блокироваться.
- Синтаксис
- select {
- case val := <-ch1:
- // обработка данных из ch1
- case ch2 <- msg:
- // отправка данных в ch2
- default:
- // выполняется, если ни один канал не готов (необязательно)
- }
- Пример использования
- package main
- import (
- "fmt"
- "time"
- )
- func main() {
- //Создаётся канал ch типа int.
- ch := make(chan int)
- //В отдельной горутине через 2 секунды в канал отправляется значение 42.
- go func() {
- time.Sleep(2 * time.Second)
- ch <- 42
- }()
- //В основном потоке выполняется select: если из канала приходит
- значение - оно выводится, если нет - через 3 секунды срабатывает таймаут
- select {
- case val := <-ch:
- fmt.Println("Получено значение из канала:", val)
- case <-time.After(3 * time.Second):
- fmt.Println("Таймаут ожидания")
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement