Давайте начнем с определений и различий между конкурентностью и параллелизмом:
1. concurrency_vs_parallelism.go
— Определения и различия:
// concurrency_vs_parallelism.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package main import ( "fmt" "time" ) func main() { fmt.Println("Concurrency vs Parallelism") // Конкурентность (Concurrency) - это когда два или более задачи могут начинаться, // выполняться и завершаться в перекрывающиеся временные промежутки, не обязательно одновременно. // Это свойство системы, в которой несколько процессов выполняются в единицу времени, // и может быть достигнуто даже на одноядерном процессоре. // Параллелизм (Parallelism) - это когда две или более задачи выполняются одновременно. // Это требует аппаратной поддержки с несколькими исполнительными путями (например, многоядерный процессор). // Примеры будут представлены в отдельных файлах. } |
Теперь рассмотрим примеры применения конкурентности и параллелизма:
2. concurrency_example.go
— Пример конкурентности:
// concurrency_example.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package main import ( "fmt" "time" ) // Функция, имитирующая выполнение какой-то работы. func doWork(workerID int) { for i := 0; i < 5; i++ { fmt.Printf("Worker %d is doing work %d\n", workerID, i) time.Sleep(500 * time.Millisecond) } } func main() { // Запуск двух горутин для демонстрации конкурентности. // Обе горутины будут выполняться независимо друг от друга. go doWork(1) go doWork(2) // Даем горутинам время на выполнение. time.Sleep(3 * time.Second) fmt.Println("Finished doing concurrent work") } |
3. parallelism_example.go
— Пример параллелизма:
// parallelism_example.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package main import ( "fmt" "runtime" "sync" ) // Функция, имитирующая выполнение какой-то работы. func doHeavyWork(workerID int, wg *sync.WaitGroup) { defer wg.Done() for i := 0; i < 5; i++ { fmt.Printf("Worker %d is doing heavy work %d\n", workerID, i) // Представим, что это тяжелая работа, требующая времени. runtime.Gosched() // Уступаем время другим горутинам. } } func main() { // Устанавливаем количество используемых ядер процессора равным 2 для демонстрации параллелизма. runtime.GOMAXPROCS(2) var wg sync.WaitGroup // Запуск двух горутин, которые могут выполняться параллельно (если есть несколько ядер). wg.Add(2) go doHeavyWork(1, &wg) go doHeavyWork(2, &wg) // Ожидаем завершения обеих горутин. wg.Wait() fmt.Println("Finished doing parallel work") } |
В этих примерах предполагается, что на вашей машине доступно несколько ядер для демонстрации параллелизма. Пример с конкурентностью (concurrency_example.go
) покажет, как задачи выполняются «как бы одновременно», переключаясь между собой, в то время как пример с параллелизмом (parallelism_example.go
) покажет реальное одновременное выполнение задач на разных ядрах процессора, если таковые имеются.