Начальный уровень

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

Это первая статья из серии руководств, которая содержит следующее:

  1. Перейти к параллелизму с GoRoutines
  2. Перейти к параллелизму с WaitGroup
  3. Перейти к параллелизму с каналами
  4. Перейти к параллелизму с Mutex
  5. Случаи использования Go Concurrency

Введение

В этой статье мы сосредоточимся на использовании GoRoutines. Перед этим позвольте мне сначала объяснить параллелизм. Обычно большая программа состоит из нескольких подпрограмм, и эти задачи будут выполняться по порядку или в последовательности без параллельного программирования. Однако, если вы сможете найти способ разделить все приложение на несколько независимых компонентов и выполнять их не по порядку, при этом получая одинаковые результаты, вы выиграете от использования параллелизма, поскольку он позволяет двум или более задачам выполняться одновременно.

В Golang параллелизм достигается с помощью GoRountines, которая представляет собой просто функцию с ключевым словом «go» перед ней, и она может работать одновременно с другими функциями.

Что происходит ?

package main
import "fmt"
func main() {
  go print()
  fmt.Println("hello from main")
}
func print() {
  for i := 0; i < 5; i++ {
    fmt.Println("hello from goroutine")
  }
}

Вы можете заметить, что приведенный выше код выводит только сообщение «привет от основного», а не «привет от горутины». Это связано с тем, что сама основная функция также является GoRoutine, которая выполняется одновременно с нашей функцией печати. В этом случае основная программа GoRoutine не будет ждать завершения другой процедуры GoRoutine, а немедленно выполнит строку fmt.Println("hello from main") и завершит работу до того, как print() может распечатать свое сообщение.

В ожидании горунтина

package main
import (
  "fmt"
  "time"
)
func main() {
  go print()
  time.Sleep(1 * time.Second)
  fmt.Println("hello from main")
}
func print() {
  for i := 0; i < 5; i++ {
    fmt.Println("hello from goroutine")
  }
}

Во втором примере основная программа GoRoutine вынуждена заснуть на секунду, прежде чем напечатать сообщение «привет от основной». Теперь вы сможете видеть сообщения от функции print(), потому что у нее достаточно времени, чтобы выполнить свою работу до выхода из основной функции. В этом примере вы можете рассматривать функцию time.Sleep() как «блокировщик», который блокирует основную программу GoRoutine на одну секунду. Еще одним потенциальным «блокировщиком» может быть fmt.Scanln(). Однако на практике это не очень хорошая идея для управления и синхронизации GoRoutines, особенно когда приложение содержит несколько GoRoutines и когда вам необходимо установить связь между GoRoutines. В будущих руководствах концепции WaitGroup и Channels будут представлены для управления GoRoutines.

Ну наконец то…

package main
import (
"fmt"
"time"
)
func main() {
  go printCat()
  go printDog()
  time.Sleep(1 * time.Second)
  fmt.Println("hello from main")
}
func printCat() {
  for i := 0; i < 5; i++ {
    fmt.Println("Cat")
  }
}
func printDog(){
  for i := 0; i < 5; i++ {
    fmt.Println("Dog")
  }
}

Давайте попробуем понять пример с несколькими GoRoutines. В этом третьем примере у нас есть три GoRoutines. Два из них являются явными: printCat() и printDog(). Третий — неявный основной GoRoutine. Запустив этот скрипт, вы можете предположить, что сначала увидите пять «Кошек», а затем пять «Собаки», напечатанные в терминале. Однако это не так, потому что и printCat(), и printDog() выполняются одновременно, и вы никогда не узнаете порядок выполнения без использования блокирующих концепций, таких как как группа ожидания и каналы.

В следующем уроке мы рассмотрим группы ожидания и поймем, как это можно связать с GoRoutines для обеспечения ожидаемых результатов.

Быть в курсе!

Alpha Reply — это компания группы Reply, миссией которой является помощь финансовым учреждениям в достижении их ИИ и цифровых преобразований.