Go Scheduler’a Giriş

Go'da Nesne Yönelimli Programlamaya Giriş

Go ve Golang programlamada, işleri çok işlemli bir ortamda dağıtmaktan bir zamanlayıcı sorumludur. Mevcut kaynaklar sınırlı olduğunda, yapılması gereken işi en verimli şekilde yönetmek zamanlayıcının görevidir. Go’da, zamanlayıcı, özellikle eşzamanlılık açısından yararlı olan goroutinlerin zamanlanmasından sorumludur. Goroutine’ler işletim sistemi iş parçacıkları gibidir, ancak çok daha hafiftirler. Bununla birlikte, goroutine’ler her zaman temeldeki işletim sistemi iş parçacığı modelinin yardımını alır ve üzerinde çalıştığı zamanlayıcı, işletim sistemi zamanlayıcısından çok daha yüksek bir seviyededir. Bu Go programlama öğreticisi, Go planlayıcının arkasındaki kavramlara hızlı bir bakış sağlar.

Bir tazelemeye ihtiyacınız varsa, eğiticimizde goroutinler hakkında daha fazla bilgi edinebilirsiniz: Goroutines’e Giriş.

Go’da CPU Zamanlayıcı nedir?

Günümüzde CPU’lar birden çok çekirdekle birlikte gelir – bu çok çekirdekli işlemciler, aynı anda yürütmeyi işlemek için optimize edilmiştir – aynı zamanda şu şekilde de bilinir: paralel işleme. Bu, donanım düzeyinde gerçekleşir ve işlemcilerin temel işlevlerine dahil edilmiş çoklu işlem becerisine sahip olmak güzeldir. Ancak sorun şu ki, gelen birden çok işi yöneten ve bunları mevcut işlemciler arasında dağıtan bir şey olmalı. Bu, zamanlayıcının işidir ve süreç olarak bilinir. zamanlama. A zamanlayıcı işleri yazılım düzeyinde planlar ve işletim sistemi işlevselliğinin temel bir parçasıdır. İşletim sisteminin bir parçası olan bir zamanlayıcı, işletim sisteminin karmaşıklıklarının ve çalışma mekanizmalarının çok iyi farkındadır; ayrıca, zamanlayıcı, üzerinde çalıştığı donanım düzeninin farkında olmalıdır. Bu, zamanlayıcıyı karmaşık bir yazılım parçası yapar. Yani, kısaca:

  • Bir zamanlayıcının işi, mevcut kaynaklar üzerinde iş dağılımı üzerinde bir çeşit kontrol sağlamaktır.
  • Bu Go eğitiminde şundan bahsettiğimizi anlayın: süreç zamanlayıcıları. Ağlar ve kapsayıcılar için de bir zamanlayıcı olabilir. Ancak, bir zamanlayıcının temel fikri aynı kalır.

Go’nun Çalışma Zamanı Zamanlayıcısı

Go çalışma zamanı zamanlayıcısı, goroutinleri zamanlar. Goroutine, tek bir işletim sistemi iş parçacığında yürütme yeteneğine sahip hafif bir iş parçacığıdır. İşletim sistemi iş parçacıkları, tek veya birden çok kullanılabilir işlemci üzerinde çalışır. Go’nun çalışma zamanı zamanlayıcısı, goroutinleri birden çok iş parçacığına dağıtır. Zamanlayıcı, goroutinin durumunu belirler. Goroutinin bir yaşam döngüsü üç temel durumdan birinde olabilir: koşma, çalıştırılabilirve çalıştırılamaz (IO engellenmiş veya sistem çağrısı nedeniyle):

Go, adı verilen bir tür zamanlayıcı üzerinde çalışır. m:n planlayıcı (M:N planlayıcı)Hangi hallerde M goroutine sayısı dağıtılabilir N işletim sistemi iş parçacığı sayısı. Nispeten, işletim sistemi iş parçacıkları, goroutinlerden çok daha fazla ek yüke sahiptir. Bu nedenle Go, maksimum sayıda goroutini çalıştırmak için sınırlı sayıda iş parçacığı kullanır.

Tamamen işletim sistemi tarafından yönetilen çekirdek düzeyindeki iş parçacıklarına benzer şekilde, goroutinler, tamamen Go çalışma zamanı tarafından yönetilen kullanıcı alanı iş parçacıklarıdır ve çalışma zamanı zamanlayıcısı bunları zamanlar. Bu, goroutinleri çekirdek iş parçacıklarından daha ucuz, daha hafif yapar ve çok küçük bir bellek ayak izi üzerinde çalışırlar (ilk yığın boyutu 2kbbir iş parçacığının varsayılan yığın boyutu ise 8kb).

Çalıştırılabilir goroutinler (yukarıdaki şekilde gösterilmektedir), kullanılabilir işletim sistemi iş parçacıkları üzerinde çalışmak üzere kuyruktan seçilir ve bunlar sırayla bir veya daha fazla kullanılabilir işlemci üzerinde çalışır. Engellenen goroutinler bir çalıştırılamaz durum kuyruğu. Engelleme kaldırıldıktan sonra, goroutine tekrar çalıştırılabilir kuyruğa girer ve mevcut işletim sistemi iş parçacığında çalışma sırasının bekler.

Go’da Fork-join Eşzamanlılık Modeli

Git kullanır fork-join eşzamanlı yürütme stratejisi programları paralel olarak yürütmek için. Bu, Go programının ana dalıyla birlikte çalıştırılmak üzere kendi yürütme yolunu dallandırmasını sağlar. Bu bölme dalı daha sonraki bir noktada çakışabilir ve tek bir yürütme yolu olarak çalışabilir. Modelin çatal kısmı, kodun belirlenen noktalarda dallara ayrıldığını ve birleştirme kısmı, yürütme bittikten sonra arayana tekrar birleştiğini belirtir. Bunu bir örnek yardımıyla anlamaya çalışalım. Go ve Golang’da fork-join eşzamanlılığının nasıl gerçekleştirileceğini gösteren basit bir program:

package main
import (
	"fmt"
    	"time"
)
func f1() {
	fmt.Println("func 1")
}
func f2() {
	fmt.Println("func 2")
}
func main() {
	fmt.Println("Start...")
	go f1()
	go f2()
	fmt.Println("End")
	time.Sleep(1 * time.Second)
}

Bu, entegre geliştirme ortamınızı (IDE) çalıştırdığınızda aşağıdaki çıktıyı üretir:

Start...
End
func 2
func 1

Golang Zamanlayıcı öğreticisi

bu ana yöntem, doğrusal bir yürütme yolu ile başlar ve belirtilen bölme noktası, işlev çağrısıdır. Git anahtar kelime (git func1()). Benzer şekilde, başka bir işlev çağrısı, func2’ye git() başka bir yürütme yoluna ayrılır. Her iki işlev de yürütmeyi bitirdikten sonra kaynağa geri döner. Ana program, zaman.Uyku(1*zaman.Saniye) çocuk dalları bu arada yürütmelerini bitirsin diye sabit bir süre için.

Satırı yorumlayarak aynı kodu çalıştırmayı deneyin: zaman.Uyku(1*zaman.Saniye). Çıktı aşağıdaki gibi olacaktır:

Start...
End

çıkış func1 ve func2 görüntülenmeyecek. Bunun nedeni, ana programın alt dallara ayrılmadan ve yeniden katılmadan önce sona ermesidir. Bu, şu anlama gelir: ana goroutine, çatallı çocuk ebeveynine yeniden katılana kadar beklemek zorundadır. İşlev Uyku zamanı bu durumda kuvvet beklemeyi mümkün kılar. Eşzamanlı yürütme kodu yazmanın daha iyi bir yolu, WaiteGrubu itibaren senkronizasyon paket.

Okumak: Go’da Çöp Toplama Anlama

Go’da WaiteGroup’u Kullanma

Yukarıdaki Go kodunu kullanarak yeniden yazabiliriz. WaiteGrubu. bu WaiteGrubu kullanılan bir engelleme mekanizmasıdır. Bekle tüm goroutinelerin idamlarını bitirmeleri ve bir kez daha, Bekle Ebeveynlerine tekrar katılana kadar. Böylece yukarıdaki kodu bu örneğe yeniden yazabiliriz:

package main

import (
	"fmt"
	"sync"
)

func f1(wg *sync.WaitGroup) {
	defer wg.Done()
	fmt.Println("func 1")
}

func f2(wg *sync.WaitGroup) {
	defer wg.Done()
	fmt.Println("func 2")
}

func main() {
	var wg sync.WaitGroup
	fmt.Println("Start...")
	wg.Add(2)
	go f1(&wg)
	go f2(&wg)
	fmt.Println("End")
	wg.Wait()
}

aradığımıza dikkat edin Ekle beklenecek goroutine sayısını ayarlamak için. Her goroutine çağırır Tamamlandı yürütmesini bitirdiğinde. bu Beklemek işlevi, programın son sonlandırılmasından önce tüm yürütmenin üst öğeye yeniden katılmasını sağlar.

Golang’da Adil Planlama Stratejisi

Eşzamanlı yürütmeyle ilgili sorunlardan biri, yeterince kullanılmayan işlemcidir. rağmen adil zamanlama stratejisi yürütme yükünü mevcut tüm işlemcilerle paylaşmaya çalışır, her zaman böyle değildir, çünkü dağıtılmış görevlerin çoğu diğer görevlere bağlıdır. Bu, birden fazla kullanılabilir işlemci arasında yük paylaşımını eşitsiz hale getirir. Bazı işlemcilerin aslında diğerlerinden daha fazla kullanılma olasılığı her zaman vardır. Ayrıca, goroutinleri yönetmek için küresel bir kilit tutmak pahalıdır. Ağır IO blok programları, önemli bir ek yük olan OS iş parçacıklarının sürekli olarak önceden alınmasına eğilimlidir. Sorunun basit bir geçici çözümü iş hırsızlığı.

Go planlayıcısı, iş çalma stratejisi, mantıksal olarak yeterince kullanılmayan herhangi bir işlemci arar ve çalıştırılabilir goroutinlerin yürütmesi için bir miktar işlem süresi çalar.

Golang Zamanlayıcı Üzerine Son Düşünceler

Bunlar, Go zamanlayıcısının çalışma sürecine hızlı bakışlardır. Go planlayıcının çok hızlı bir şekilde geliştiğini ve geliştiricilerin nasıl çalıştığına dair küçük veya önemli değişiklikler yaparak performansı sürekli olarak iyileştirmeye çalıştıklarını anlayın. Ancak temel ilkeler aynı kalır. Burada sadece yüzeyi çizdik ve Go zamanlayıcıya çok yüksek düzeyde bir genel bakış sunmaya çalıştık.

Devamını oku Go ve Golang programlama eğitimleri.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.