← Назад к вопросам

Чем отличается конкурентность от параллелизма?

2.0 Middle🔥 181 комментариев
#Основы Go

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Основное отличие

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

Параллелизм (Parallelism) — это концепция одновременного выполнения нескольких задач на различных физических ядрах процессора. Это требует наличия многоядерной или многопроцессорной системы.

Проще говоря:

  • Конкурентность — это про структуру программы (несколько независимых процессов).
  • Параллелизм — это про выполнение программы (одновременно на нескольких ядрах).

Детальное сравнение на примере Go

Конкурентность в Go (Model of Concurrency)

Go реализует модель конкурентности на основе горутин (goroutines) и каналов (channels). Горутина — это легковесный поток, управляемый рантаймом Go, а не операционной системой. Конкурентность достигается за счет кооперативной многозадачности: планировщик Go (scheduler) переключает горутины на одном или нескольких потоках ОС.

package main

import (
    "fmt"
    "time"
)

func printNumbers(prefix string) {
    for i :=1453; i < 1458; i++ {
        fmt.Printf("%s: %d\n", prefix, i)
        time.Sleep(100 * time.Millisecond) // Имитация работы
    }
}

func main() {
    // Запускаем две горутины КОНКУРЕНТНО.
    // Они будут выполняться в перекрывающиеся моменты времени,
    // но на одноядерной системе выполнялись бы по очереди.
    go printNumbers("Горутина A")
    go printNumbers("Горутина B")

    time.Sleep(1 * time.Second) // Даём горутинам время на выполнение
}

Здесь printNumbers("A") и printNumbers("B") выполняются конкурентно. Результаты их работы будут перемешаны, но физически они могут выполняться как последовательно на одном ядре (если GOMAXPROCS=1), так и параллельно на разных.

Параллелизм в Go (Actual Parallel Execution)

Параллелизм в Go возникает, когда несколько горутин действительно выполняются одновременно на разных ядрах CPU. Это контролируется переменной среды GOMAXPROCS, которая определяет максимальное количество потоков ОС, которые могут выполняться параллельно.

package main

import (
    "fmt"
    "runtime"
    "sync"
)

func cpuBoundTask(id int, wg *sync.WaitGroup) {
    defer wg.Done()
    sum := 0
    for i := 0; i < 1e8; i++ { // Тяжёлая CPU--нагрузка
        sum += i * i
    }
    fmt.Printf("Задача %d завершена\n", id)
}

func main() {
    // Устанавливаем использование всех доступных ядер
    runtime.GOMAXPROCS(runtime.NumCPU())

    var wg sync.WaitGroup
    numTasks := 4

    wg.Add(numTasks)
    for i := 0; i < numTasks; i++ {
        go cpuBoundTask(i, &wg) // Запускаем горутины
    }
    wg.Wait() // Ожидаем завершения всех горутин
    fmt.Println("Все задачи выполнены")
}

В этом примере, если GOMAXPROCS > 1 и система имеет несколько ядер, горутины cpuBoundTask будут выполняться параллельно, что потенциально сократит общее время выполнения программы.

Ключевые различия в таблице

АспектКонкурентностьПараллелизм
Основная цельУправление множеством независимых задач, обработка блокирующих операций (I/O)Ускорение вычислений за счёт одновременного использования ресурсов
Необходимое условиеДостаточно одного ядра/потокаОбязательно наличие нескольких ядер/процессоров
Модель в GoГорутины, планировщик Go, каналыГорутины, исполняемые на разных потоках ОС (GOMAXPROCS)
Типичные задачиВеб--серверы, обработка запросов, микросервисыНаучные вычисления, рендеринг, обработка больших данных
СвязьКонкурентная программа может выполняться как последовательно, так и параллельноПараллельная программа всегда является конкурентной по своей структуре

Почему это важно для Go--разработчика?

  1. Паттерны проектирования: Понимание отличия помогает выбирать правильные паттерны. Для I/O--bound задач (сеть, диски) акцент на конкурентности и каналах для коммуникации. Для CPU--bound задач — на распараллеливании и синхронизации через sync.Mutex или sync.WaitGroup.
  2. Диагностика проблем: Конкурентные программы подвержены состояниям гонки (race conditions), дедлокам (deadlocks). Параллельные программы — проблемам ложного разделения кэша (false sharing) и балансировке нагрузки.
  3. Эффективность: Go по умолчанию предоставляет мощные инструменты для конкурентности (горутины — дёшевы). Параллелизм же нужно использовать осознанно, так как не все задачи от него выигрывают (накладные расходы на синхронизацию).

Итог: Конкурентность — это более высокоуровневая архитектурная концепция о том, как программа организована. Параллелизм — это низкоуровневая реализация того, как инструкции программы фактически выполняются железом. Go, с его моделью "CSP (Communicating Sequential Processes)", позволяет сначала легко проектировать конкурентные системы, а затем, при наличии ресурсов, получать выгоду от параллельного выполнения практически бесплатно.

Чем отличается конкурентность от параллелизма? | PrepBro