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

Goroutines (Горутины) Goroutines (Горутины) — это легковесные потоки выполнения, которые работают параллельно с другими Goroutines в одном адресном пространстве. Чтобы создать горутину, нужно использовать оператор go перед вызовом функции. При этом функция будет выполняться асинхронно с вызвавшим её участком кода. Пример:

func main() {
    go sayHello()
    fmt.Println("Main function")
}

func sayHello() {
    fmt.Println("Hello from goroutine")
}

В этом примере мы создаем новую Goroutine, используя ключевое слово go, и вызываем функцию sayHello() в новой Goroutine. Затем функция main выводит "Main function" на консоль. Когда мы запустим этот код, мы увидим вывод "Main function" и "Hello from goroutine", которые будут выведены на консоль. Порядок этих выводов может отличаться, поскольку goroutine выполняется одновременно с основной функцией.

Программы Goroutine имеют небольшой вес и занимают мало места в памяти, что позволяет легко создавать многие из них в рамках одной программы. Это позволяет разработчикам создавать приложения с высокой степенью параллелизма, которые могут использовать преимущества современных многоядерных процессоров.

Channels (Каналы) Channels (Каналы) - это способ, с помощью которого Goroutine могут взаимодействовать друг с другом и синхронизировать свое выполнение. Канал - это типизированный канал, по которому Goroutine могут отправлять и получать значения. Каналы могут быть созданы с помощью функции make, а значения могут отправляться и приниматься с помощью оператора <-

Пример:

func main() 
    c := make(chan int)
    go produce(c)
    go consume(c)
    time.Sleep(1 * time.Second)
}

func produce(c chan int) {
    for i := 0; i < 5; i++ {
        c <- i
    }
}

func consume(c chan int) {
    for i := range c {
        fmt.Println(i)
    }
} 

В этом примере мы создаем новый канал типа int с помощью функции make. Затем мы создаем две Goroutines - product и consume. Программа produce отправляет значения в канал с помощью оператора <-, а Goroutine consume получает значения из канала с помощью ключевого слова range.

Когда мы запустим этот код, мы увидим вывод "0 1 2 3 4", выведенный на консоль. Функция time.Sleep используется для гарантии того, что программа не завершит работу до завершения выполнения подпрограмм.

Wait Groups (Группы ожидания) Wait Groups (Группы ожидания) - это способ синхронизации выполнения нескольких программ. Группа ожидания - это структура, которая содержит три метода: Add и Done, а также метод ожидания. Метод Add увеличивает счетчик группы ожидания, метод Done уменьшает счетчик, а метод Wait блокирует до тех пор, пока счетчик не достигнет нуля.

Пример:

func main() 
    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go sayHello(&wg, i)
    }

    wg.Wait()
}

func sayHello(wg *sync.WaitGroup, id int) {
    defer wg.Done()
    fmt.Printf("Hello from goroutine %dn", id)
} 

В приведенном выше коде мы создаем Wait Groups и добавляем в нее пять goroutines . Каждая goroutines выполняет один и тот же код одновременно и по завершении вызывает функцию "Done". Наконец, мы вызываем функцию "Wait", чтобы дождаться завершения всех goroutines, прежде чем продолжить выполнение.

Спасибо за прочтение, не забудь подписаться на канал и поставить ❤️

#golang #goroutines #channels #waitgroup #concurrency #developer #programming