Ответ
Конкурентность (Concurrency) — это способность программы декомпозировать задачи на независимые части и выполнять их в произвольном порядке (например, с помощью горутин и каналов в Go). Это о структурировании программы для обработки нескольких вещей одновременно.
Параллелизм (Parallelism) — это одновременное выполнение этих задач на нескольких ядрах CPU или процессорах. Это о фактическом выполнении нескольких вещей в один и тот же момент времени.
Ключевое отличие:
- Конкурентность — логическая модель. Программа может быть конкурентной, но выполняться на одном ядре CPU через быстрое переключение контекста (мультиплексирование).
- Параллелизм — физическое выполнение. Требует наличия нескольких ядер CPU или процессоров для одновременного выполнения задач.
Пример:
package main
import (
"fmt"
"runtime"
"time"
)
func task(name string) {
for i := 0; i < 3; i++ {
fmt.Printf("Task %s: %dn", name, i)
time.Sleep(100 * time.Millisecond)
}
}
func main() {
// Конкурентность: запуск двух горутин.
// Они могут выполняться на одном ядре (чередуясь) или на разных (параллельно),
// в зависимости от планировщика Go и доступных ресурсов.
go task("A")
go task("B")
// Параллелизм: Go-рантайм по умолчанию использует GOMAXPROCS,
// равный количеству логических ядер CPU. Если доступно более одного ядра,
// горутины могут выполняться параллельно.
// Можно явно установить GOMAXPROCS, чтобы ограничить или увеличить количество ядер.
// Например, для принудительного использования 2 ядер:
// runtime.GOMAXPROCS(2)
fmt.Printf("Number of logical CPUs: %dn", runtime.NumCPU())
fmt.Printf("GOMAXPROCS: %dn", runtime.GOMAXPROCS(0)) // GOMAXPROCS(0) возвращает текущее значение
// Даем время горутинам завершиться
time.Sleep(1 * time.Second)
fmt.Println("Main finished")
}
Go делает конкурентность простой и естественной благодаря горутинам и каналам, а параллелизм становится возможным, когда есть доступные аппаратные ресурсы и GOMAXPROCS
позволяет их использовать.