Написание вашей первой конкурентной программы на Go в Ubuntu
Язык программирования Go от Google существует с 2009 года, а в 2012 году язык достиг официального статуса v1.0. За эти годы многое изменилось, в том числе и способ установки языка. В начале своего пути не было официальных бинарных дистрибутивов, и вам приходилось либо собирать Go из исходного кода, что было рекомендованным методом, поскольку язык часто менялся, либо использовать предварительно собранный пакет для вашего дистрибутива Linux. В то время поддержка Windows была ограничена, как и поддержка архитектур процессоров, отличных от Intel.
С тех пор ситуация значительно улучшилась. Для Linux есть два простых способа установить Go. Скачайте официальный бинарный дистрибутив Linux со страницы загрузок Go или выберите предварительно собранный пакет для вашего дистрибутива Linux. Самый простой способ установить Go на Ubuntu — использовать apt-get:
sudo apt-get install golangПосле установки Go вы можете начать разрабатывать программы. Одной из самых простых программ на Go является классическая программа “Hello World!”. Используя текстовый редактор, создайте файл с именем “ hellomte.go “ со следующим коротким кодом на Go:
package main
import "fmt"
func main() {
fmt.Println("Hello Make Tech Easier!")
}С версии v1.0 Go необходимость в отдельных командах компиляции и линковки была устранена, и старые команды 8g и 8l были заменены на команду go.
Чтобы запустить hellomte.go, откройте терминал и перейдите в каталог, содержащий файл исходного кода, затем введите:
go run hellomte.goЭто скомпилирует и запустит программу на Go, но не создаст исполняемый бинарный файл. Чтобы создать бинарный файл и затем запустить его, используйте команду go build:
go build hellomte.go
./hellomteСила конкурентности
Одной из определяющих особенностей языка программирования Go является его поддержка конкурентности, которая позволяет программе работать с несколькими задачами одновременно. Параллелизм, который похож на конкурентность, позволяет программе выполнять множество задач одновременно, но конкурентность идет на шаг дальше, позволяя этим отдельным задачам общаться и взаимодействовать. В результате Go позволяет программистам использовать множество различных конкурентных конструкций, включая пулы рабочих, конвейеры (где одна задача происходит после другой) и синхронные или асинхронные фоновые задачи. Основой этой конкурентности являются goroutine, связанные с channels и оператором select в Go.
Вот простая программа на Go, которая выводит строку несколько раз, используя конкурентную goroutine:
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
fmt.Println(s)
}
}
func main() {
go say("Hello Make Tech Easier!")
fmt.Println("Sleep a little...")
time.Sleep(100 * time.Millisecond)
}Функция say() просто выполняет простой цикл, чтобы напечатать строку (параметр s) пять раз. Интересно, как вызывается эта функция. Вместо того чтобы просто вызвать say("Hello Make Tech Easier!"), перед вызовом функции ставится ключевое слово go. Это означает, что функция будет запущена как отдельная задача. Остальная часть функции main() просто спит немного, чтобы дать время для завершения goroutine.
Вывод может вас удивить:

Как вы можете видеть, функция say() выполняется как goroutine, и пока она настраивается, остальная часть функции main() продолжает работу, выводя “Sleep a little…” и затем засыпая. К этому времени goroutine активна и начинает выводить строку пять раз. Наконец, программа завершается, как только истекает лимит времени.
Каналы
goroutines могут общаться, используя каналы. Канал открывает линию связи между двумя различными частями программы на Go. Обычно функция вызывается как goroutine, и если ей нужно отправить данные (например, из сетевой операции), она может использовать канал для передачи этих данных. Если другая часть программы на Go ожидает эти данные, она будет спать, пока данные не будут готовы. Каналы создаются с помощью функции make(), и их можно передавать в качестве параметров в goroutines.
Рассмотрим этот код:
package main
import (
"fmt"
)
func say(s string, c chan int) {
var i int
for i = 0; i < 5; i++ {
fmt.Println(s)
}
c <- i
}
func main() {
c := make(chan int)
go say("Hello Make Tech Easier!", c)
sts := <- c
fmt.Println(sts)
}Функция say() очень похожа на первый пример с тем исключением, что второй параметр — это канал, и что после вывода строки количество итераций будет отправлено по каналу через строку кода c <- i.
Главная функция создает канал, запускает функцию say() как goroutine и затем ждет, пока данные не поступят по каналу, sts := <- c, прежде чем вывести результат.
Заключение
Язык Go значительно продвинулся за последние несколько лет, если вы не смотрели на него недавно, возможно, сейчас хорошее время!