Что такое конкурентность (concurrency) в Go и чем она отличается от параллелизма?

Ответ

Конкурентность (concurrency) — это структура программы, позволяющая работать с несколькими задачами одновременно, управляя их независимым выполнением. Это не означает, что они выполняются в один и тот же момент времени.

Параллелизм (parallelism) — это исполнение нескольких задач одновременно, например, на разных ядрах процессора.

«Конкурентность — это не параллелизм. Конкурентность — это способ структурирования, а параллелизм — это исполнение.» — Роб Пайк

Go предоставляет мощные инструменты для построения конкурентных программ, которые могут выполняться параллельно, если позволяет оборудование.

Основные инструменты в Go:

  1. Горутины (Goroutines): Легковесные потоки, управляемые средой выполнения Go, а не операционной системой. Их создание очень дешево (тысячи и миллионы горутин).
  2. Каналы (Channels): Типизированные конвейеры для безопасной передачи данных между горутинами. Они позволяют синхронизировать выполнение и избегать гонок данных.
  3. Пакет sync: Предоставляет традиционные примитивы синхронизации, такие как Mutex, RWMutex и WaitGroup.

Пример с использованием WaitGroup для ожидания завершения горутин:

package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done() // Уменьшаем счетчик WaitGroup после завершения функции

    fmt.Printf("Рабочий %d началn", id)
    time.Sleep(100 * time.Millisecond)
    fmt.Printf("Рабочий %d закончилn", id)
}

func main() {
    var wg sync.WaitGroup // Создаем WaitGroup

    for i := 1; i <= 3; i++ {
        wg.Add(1) // Увеличиваем счетчик на 1 для каждой горутины
        go worker(i, &wg)
    }

    wg.Wait() // Блокируем выполнение, пока счетчик не станет равен 0
    fmt.Println("Все рабочие завершили свою работу.")
}