Menu
Coddy logo textTech

Основы горутин

Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy — урок 59 из 107.

Горутина (goroutine) — это легковесный поток выполнения, управляемый средой выполнения Go. В отличие от традиционных потоков, которые потребляют значительный объем памяти, горутины запускаются всего с несколькими килобайтами стековой памяти, что позволяет запускать тысячи таких потоков одновременно.

Чтобы запустить горутину, просто добавьте ключевое слово go перед вызовом функции:

func sayHello(name string) {
    fmt.Println("Hello,", name)
}

func main() {
    go sayHello("Alice")  // выполняется конкурентно
    go sayHello("Bob")    // выполняется конкурентно
    
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Done")
}

Когда выполняется go sayHello("Alice"), она не ждет завершения sayHello. Вместо этого выполнение сразу переходит к следующей строке, пока sayHello работает в фоновом режиме. Вот почему нам нужен time.Sleep — без него main завершится до того, как горутины успеют завершить свою работу.

Вы также можете запускать горутины с помощью анонимных функций:

go func(msg string) {
    fmt.Println(msg)
}("Hello from goroutine")

Сама функция main выполняется в горутине. Когда она завершается, все остальные горутины немедленно прекращаются — у них нет возможности завершиться. Использование time.Sleep — это временное решение; в следующих уроках вы изучите правильные методы синхронизации с помощью каналов и групп ожидания.

challenge icon

Задание

Легко

Давайте создадим планировщик задач, который выполняет несколько задач одновременно, используя goroutines. Вы создадите простую систему, в которой задачи выполняются в фоновом режиме, пока основная программа продолжает работу, демонстрируя, как goroutines обеспечивают параллельное выполнение.

Вы организуете свой код в двух файлах:

  • tasks.go: Определите логику выполнения ваших задач.

    Создайте структуру Task с полями Name (string) и Duration (int, представляющее миллисекунды).

    Реализуйте метод Run() для Task, который имитирует работу, засыпая на время длительности задачи, а затем выводит: Task [Name] completed

    Создайте функцию RunAllTasks(tasks []Task), которая запускает метод Run() каждой задачи как goroutine. После запуска всех goroutines она должна заснуть на 500 миллисекунд, чтобы дать им завершиться, а затем вывести: All tasks launched

  • main.go: Считывает информацию о задачах и координирует параллельное выполнение.

    Считайте количество задач, затем считайте имя и длительность каждой задачи. Создайте задачи и передайте их в RunAllTasks. После возврата функции выведите: Main function done

Будут предоставлены следующие входные данные:

  • Строка 1: Количество задач (целое число)
  • Следующие строки: Для каждой задачи две строки — имя задачи, затем её длительность в миллисекундах

Например, при вводе:

3
Download
100
Process
50
Upload
75

Ваш вывод должен показывать завершение задач (порядок может меняться из-за параллелизма), за которым следуют сообщения о завершении:

Task Process completed
Task Upload completed
Task Download completed
All tasks launched
Main function done

Примечание: Поскольку goroutines выполняются одновременно, задачи с меньшей длительностью обычно завершаются первыми. Порядок завершения задач зависит от их длительности — более короткие задачи завершаются раньше длинных.

Используйте time.Sleep с time.Duration и time.Millisecond для задержек. Помните, что без задержки в RunAllTasks функция вернет управление до того, как goroutines завершат свою работу.

Шпаргалка

Горутина (goroutine) — это легковесный поток выполнения, управляемый средой выполнения Go. Горутины запускаются с использованием всего нескольких килобайт стековой памяти, что позволяет запускать тысячи таких потоков одновременно.

Чтобы запустить горутину, поместите ключевое слово go перед вызовом функции:

func sayHello(name string) {
    fmt.Println("Hello,", name)
}

func main() {
    go sayHello("Alice")  // выполняется конкурентно
    go sayHello("Bob")    // выполняется конкурентно
    
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Done")
}

Когда выполняется go sayHello("Alice"), программа не ждет завершения sayHello. Вместо этого она сразу переходит к следующей строке, пока sayHello выполняется в фоновом режиме.

Вы можете запускать горутины с помощью анонимных функций:

go func(msg string) {
    fmt.Println(msg)
}("Hello from goroutine")

Сама функция main выполняется в горутине. Когда она завершается, все остальные горутины немедленно прекращают работу. Используйте time.Sleep, чтобы дать горутинам завершиться до выхода из функции main.

Попробуйте сами

package main

import (
	"fmt"
)

func main() {
	// Считать количество задач
	var numTasks int
	fmt.Scanln(&numTasks)

	// TODO: Создать слайс для хранения задач
	
	// TODO: Считать название и длительность каждой задачи
	// Для каждой задачи:
	//   - Считать название задачи
	//   - Считать длительность (как целое число)
	//   - Создать Task и добавить в ваш слайс

	// TODO: Вызвать RunAllTasks с вашим слайсом задач

	// TODO: Вывести "Main function done"
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование