Menu
Coddy logo textTech

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

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

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

Чтобы запустить goroutine, просто поместите ключевое слово 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 завершилась бы до того, как goroutines завершат работу.

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

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

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

challenge icon

Задание

Легко

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

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

  • tasks.go: Define логику выполнения задач.

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

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

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

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

    Считайте number задач, затем считайте name и duration каждой задачи. Создайте задачи и передайте их в RunAllTasks. После её возврата выведите: Main function done

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

  • Line 1: Number of tasks (integer)
  • Следующие lines: для каждой задачи — две строки: name задачи, затем её duration в milliseconds

Например, если дано:

3
Download
100
Process
50
Upload
75

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

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

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

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

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

package main

import (
	"fmt"
)

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

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

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

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

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

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

Потренируйтесь самостоятельно: Онлайн-компилятор Go