Научете как goroutines и канали позволяват ефективна едновременност във вашите Go програми.

Паралелността е решаващ аспект на съвременната разработка на софтуер, тъй като позволява на програмите да се справят ефективно с множество задачи едновременно. Можете да пишете програми, които изпълняват различни операции, водещи до подобрена производителност, отзивчивост и използване на ресурсите.

Паралелността е една от характеристиките, отговорни за бързото приемане на Go. Вградената поддръжка на Go за едновременно програмиране се счита за ясна, като същевременно помага да се избегнат често срещани клопки като условия на състезание и блокирания.

Паралелност в Go

Go осигурява стабилна поддръжка за едновременност чрез различни механизми, всички налични в неговата стандартна библиотека и верига от инструменти. Go програми постигане на едновременност чрез goroutines и канали.

Goroutines са леки, независимо изпълняващи функции, които работят едновременно с други goroutines в рамките на същото адресно пространство. Goroutines позволяват множество задачи да се изпълняват едновременно без изрично управление на нишки. Goroutines са по-леки от нишките на операционната система и Go може ефективно да изпълнява хиляди или дори милиони goroutines едновременно.

instagram viewer

Каналите са комуникационният механизъм за координация и споделяне на данни между goroutines. Каналът е въведен канал, който позволява на goroutines да изпращат и получават стойности. Каналите осигуряват синхронизация, за да осигурят безопасно споделяне на данни между goroutines, като същевременно предотвратяват условия на състезание и други често срещани проблеми с паралелността.

Чрез комбиниране на goroutines и канали, Go предоставя мощен и ясен модел на паралелност, който опростява разработването на паралелни програми, като същевременно поддържа безопасност и ефективност. Тези механизми ви позволяват лесно да използвате многоядрени процесори и изграждане на силно мащабируеми и отзивчиви приложения.

Как да използвате Goroutines за едновременно изпълнение на код

Средата за изпълнение Go управлява goroutines. Goroutines имат своя стек, което им позволява да имат лек отпечатък с първоначален размер на стека от няколко килобайта.

Goroutines се мултиплексират върху няколко OS нишки от Go runtime. Планировчикът за изпълнение на Go ги планира в наличните нишки чрез ефективно разпределяне на натоварването, позволявайки едновременно изпълнение на множество goroutines на по-малко нишки на ОС.

Създаването на goroutines е лесно. Ще използвате отивам ключова дума, последвана от извикване на функция за деклариране на goroutines.

функосновен() {
отивам функция1() // Създаване и изпълнение на goroutine за функция1
отивам функция2() // Създаване и изпълнение на goroutine за функция2

// ...
}

функфункция1() {
// Код за функция1
}

функфункция2() {
// Код за функция2
}

Когато програмата извиква функция1() и функция2() с отивам ключова дума, средата за изпълнение на Go изпълнява функциите едновременно като goroutines.

Ето примерна употреба на goroutine, която отпечатва текст на конзолата:

пакет основен

импортиране (
"fmt"
"време"
)

функprintText() {
за аз := 1; аз <= 5; i++ {
fmt. Println("Отпечатване на текст", i)
време. сън(1 * време. второ)
}
}

функосновен() {
отивам printText() // Стартиране на goroutine за едновременно изпълнение на функцията printText

// Изпълнение на други задачи в основната goroutine
за аз := 1; аз <= 5; i++ {
fmt. Println(„Извършване на други задачи“, i)
време. сън(500 * време. милисекунда)
}

// Изчакайте goroutine да завърши
време. сън(6 * време. второ)
}

The printText функция многократно отпечатва някакъв текст на конзолата с a за цикъл, който се изпълнява пет пъти след забавяне от една секунда между всеки израз с времевият пакет.

The основен функция стартира goroutine чрез извикване отидете на printText, който стартира printText функция като отделна едновременна goroutine, която позволява на функцията да се изпълнява едновременно с останалата част от кода в основен функция.

И накрая, за да сте сигурни, че програмата няма да излезе преди printText goroutine завършва, the време. сън функцията поставя на пауза основната програма за шест секунди. В сценарии от реалния свят бихте използвали механизми за синхронизиране като канали или групи за изчакване, за да координирате изпълнението на goroutines.

Използване на канали за комуникация и синхронизация

Goroutines имат вградена поддръжка за комуникация и синхронизация през канали, което прави писането едновременно код по-лесен от традиционните нишки, които често изискват ръчни механизми за синхронизиране като ключалки и семафори.

Можете да мислите за каналите като за тръбопроводи за поток от данни между goroutines. Една горутина може да изпрати стойност в канала, а друга горутина може да получи тази стойност от канала. Този механизъм гарантира, че обменът на данни е безопасен и синхронизиран.

Ще използвате оператор за изпращане и получаване на данни през канали.

Ето един пример, демонстриращ основното използване на канали за комуникация между две горутини:

функосновен() {
// Създаване на небуфериран канал от тип низ
ch := направи(чанниз)

// Goroutine 1: Изпраща съобщение в канала
отивамфунк() {
ch „Здравей, Канал!“
}()

// Goroutine 2: Получава съобщението от канала
msg := fmt. Println (съобщение) // Изход: Здравей, канал!
}

Каналът в основен функция е небуфериран канал с име гл създаден с прави() функция. Първата goroutine изпраща съобщението "Hello, Channel!" в канала с помощта на оператор, а втората горутина получава съобщението от канала, използвайки същия оператор. И накрая, на основен функцията отпечатва полученото съобщение на конзолата.

Можете да дефинирате въведени канали. Ще посочите типа канал при създаването. Ето един пример, който демонстрира използването на различни типове канали:

функосновен() {
// Небуфериран канал
ch1 := направи(чанвътр)

// Буфериран канал с капацитет 3
ch2 := направи(чанниз, 3)

// Изпращане и получаване на стойности от канали
ch1 42// Изпращане на стойност в ch1
стойност1 := // Получаване на стойност от ch1

ch2 "Здравейте"// Изпращане на стойност в ch2
стойност2 := // Получаване на стойност от ch2
}

The основен функция създава два канала: гл.1 е небуфериран целочислен канал, докато ch2 е канал с буфериран низ с капацитет 3. Можете да изпращате и получавате стойности към и от тези канали, като използвате оператор (стойностите трябва да са от посочения тип).

Можете да използвате каналите като механизми за синхронизиране за координиране на изпълнението на goroutine, като използвате блокиращия характер на операциите на канала.

функосновен() {
ch := направи(чанbool)

отивамфунк() {
fmt. Println("Горутина 1")
ch вярно// Завършване на сигнала
}()

отивамфунк() {
// Изчакайте сигнала за завършване от Goroutine 1
fmt. Println("Горутина 2")
}()

// Изчакайте сигнал за завършване от Goroutine 2
fmt. Println("Основна goroutine")
}

The гл каналът е булев. Две goroutines се изпълняват едновременно в основен функция. Goroutine 1 сигнализира за завършването си чрез изпращане на a вярно стойност в канала гл. Goroutine 2 чака сигнала за завършване, като получава стойност от канала. И накрая, главната горутина изчаква сигнала за завършване от горутина две.

Можете да създавате уеб приложения в Go With Gin

Можете да създавате високопроизводителни уеб приложения в Go with Gin, като същевременно използвате функциите за паралелност на Go.

Можете да използвате Gin, за да управлявате ефективно HTTP маршрутизирането и междинния софтуер. Възползвайте се от вградената поддръжка на паралелност на Go, като използвате goroutines и канали за задачи като заявки към бази данни, API извиквания или други блокиращи операции.