Горутина
Горутина представляет собой легковесный поток выполнения,
который управляется средой выполнения Go. В отличие от
потоков операционной системы, горутины имеют значительно
меньший накладной расход и управляются планировщиком Go.
Для запуска новой горутины используется ключевое слово
go, которое ставится перед вызовом функции или
метода. Горутины позволяют выполнять несколько задач
одновременно, что делает их идеальным инструментом для
создания конкурентных программ.
Синтаксис
go functionName(arguments)
Для запуска горутины необходимо использовать ключевое
слово go, после которого указывается вызов функции
или метода. Функция может быть как именованной, так и
анонимной.
Пример
Давайте запустим горутину, которая выводит сообщение в консоль:
package main
import (
"fmt"
"time"
)
func printMessage() {
fmt.Println("Hello from goroutine")
}
func main() {
go printMessage()
time.Sleep(100 * time.Millisecond)
}
Результат выполнения кода:
"Hello from goroutine"
В этом примере мы использовали функцию time.Sleep,
чтобы дать горутине время на выполнение. Без этой задержки
программа завершилась бы до того, как горутина успела бы
вывести сообщение.
Пример
Давайте запустим несколько горутин для выполнения параллельных задач:
package main
import (
"fmt"
"sync"
)
func printNumbers() {
for i := 1; i <= 5; i++ {
fmt.Printf("%d ", i)
}
}
func printLetters() {
for i := 'a'; i <= 'e'; i++ {
fmt.Printf("%c ", i)
}
}
func main() {
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
printNumbers()
}()
go func() {
defer wg.Done()
printLetters()
}()
wg.Wait()
fmt.Println()
}
Результат выполнения кода:
"1 2 3 4 5 a b c d e "
В этом примере мы использовали sync.WaitGroup
для ожидания завершения всех горутин. Без этого механизма
главная горутина завершилась бы до того, как дочерние
горутины успели бы выполниться.
Пример
Давайте продемонстрируем конкурентное выполнение горутин с анонимными функциями:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("Goroutine %d started\n", id)
}(i)
}
wg.Wait()
}
Результат выполнения кода:
"Goroutine 2 started"
"Goroutine 0 started"
"Goroutine 1 started"
Обратите внимание, что порядок выполнения горутин не гарантирован - планировщик Go решает, в каком порядке выполнять горутины. Поэтому вывод может отличаться при каждом запуске программы.
Смотрите также
-
основы конкурентности в
пакете asyn,
которые дают представление об асинхронном программировании -
механизм синхронизации
sync.WaitGroup,
который позволяет ожидать завершения группы горутин -
каналы
chan,
которые используются для обмена данными между горутинами -
оператор
select,
который позволяет ожидать несколько операций с каналами