Programlama

Go’da İşletim Sistemi Sinyalleri Nasıl Kullanılır?

Go programlama dili, C gibi sistem düzeyinde programlama için oluşturulmamıştır, ancak geliştiricilerin temel işletim sistemiyle biraz düşük düzeyde etkileşim kurmasına yardımcı olan belirli özellikler vardır; sinyaller. bu işletim sistemi/sinyaller paketi, geliştiricilerin bu özellikle çalışmasına yardımcı olur. Aslında bazen UNIX benzeri bir ortamda sinyallerle çalışmak gerekir. Bu Goland programlama öğreticisi, genel olarak sinyal kavramına bir bakış atıyor ve kodlayıcıların bunları bir Go programında nasıl uygulayabileceklerini gösteriyor.

Okumak: Geliştiriciler için En İyi Proje Yönetim Araçları

Go ve Golang’daki Sinyaller nelerdir?

Sinyaller, UNIX veya Linux tabanlı işletim sistemleri tarafından oluşturulan olaylardır. Sistem, üretilen sinyale göre bazı işlemler yapar. Örneğin, çalışan bir programı iptal etmek istiyorsak, CTRL+C. Bu denilen bir sinyal gönderir İŞARET bir programa aktarır ve temel sistem, üretilen sinyale göre uygun eylemi gerçekleştirir. Anlayın ki İŞARET belirli bir sinyali belirten bir sayı ile ilişkili bir addır.

Sinyaller aslında programlı olarak oluşturulabilen yazılım kesintileridir. Eşzamansız olayları işlemek için bir yol sunarlar. Tipik olarak, sinyaller, güvenli olmaları için numaralarından ziyade adlarıyla üretilir. Çoğu sinyalin ve bunların belirli eylemlerinin işletim sistemi tarafından tanımlandığını anlayın. Ayrıca işlevlerini işletim sistemi kapsamında yerine getirirler. Bu nedenle, bazı olayları işleyebilmek, sınırlı bir kullanıcıya sistemle herhangi bir şey yapmak için ücretsiz bir çalışma sağlamaz; üretilse bile işletim sistemi tarafından yok sayılan sinyaller vardır. Bir program tarafından hangi sinyallerin işlenmesine izin verildiğine karar vermek işletim sistemine bağlıdır.

Örneğin, SIGKILL ve DURDUR sinyaller yakalanamaz, engellenemez veya göz ardı edilemez çünkü bu sinyaller işletim sistemi işlevselliğinin “akıl sağlığını” korumada kritik öneme sahiptir. Çekirdek ve kök kullanıcıya, aşırı koşullar altında bir işlemi durdurmanın bir yolunu sağlarlar. ilgili numara SIGKILL dır-dir 9.

Linux’ta adında bir yardımcı program var öldürmek bu bir gönderir SIGTERM Çalışan bir programı sonlandırmak için sinyal. Desteklenen tüm sinyallerin listesini bulmanın yaygın bir yolu, terminalde aşağıdaki komutları kullanmaktır:

Go’da işletim sistemi/sinyal Paketi nasıl kullanılır?

bu işletim sistemi Go’daki paket, dosya sistemiyle çalışma, dosya ve dizin oluşturma vb. gibi işletim sistemi işlevleriyle çalışmak için platformdan bağımsız bir arabirim sağlar. alt paket, işletim sistemi/sinyal, geliştiricilerin özellikle sinyallerle çalışmasına yardımcı olur. Kullanılabilir birçok sinyal vardır, ancak tüm sinyaller bir program tarafından işlenemez. gibi sinyaller var SIGKILL ve DURDUR bir program tarafından ne çağrılabilir ne de göz ardı edilebilir. Nedeni basit: çok kritikler ve yaramaz bir program tarafından kötüye kullanılmasına izin verilmiyor.

İki tür sinyal vardır: senkron ve asenkron. Senkron sinyaller, başka bir sinyalle senkronize olanlardır, tipik olarak bir saat. Alıcıya verinin ulaştığını belirtmek için saat tarafından üretilen bir darbe kullanılır. Bu nedenle, senkron sinyalleşmede hem olay hem de olayın zamanlaması önemlidir. Senkron sinyaller tipik olarak program yürütmedeki hatalar tarafından tetiklenir. Sinyaller, örneğin SIGBUS, SIGFPEveya SIGSEGVtarafından tetiklenmedikçe işletim sistemi.Süreç.Öldür, senkron sinyaller olarak kabul edilir. Go programları, senkronize sinyalleri çalışma zamanı paniğine dönüştürür. Bu, Go’daki varsayılan davranıştır.

Asenkron sinyaller ise bir saat darbesi ile senkronize olmasını gerektirmez. Örneğin, SIGHUP kontrolünde bulunan terminalin kapandığını prosese bildirir. Kesinti karakterine basarak ürettiğimiz belki de en yaygın asenkron sinyal CTRL+C, İŞARET. Kesmeyi oluşturduğumuzda (tuşuna basarak CTRL+C) program yürütme sırasında, İŞARET sinyal gönderilir ve program hemen sonlandırılır.

Buradaki yakalamayı anlayın: sinyal İŞARET olduğunda klavye kesintisi için bir sinyaldir CTRL+C basılır; aslında değil programı sonlandırın. Bu basitçe, belirli bir klavye kesmesinin oluşturulduğu ve kesmeyi gerçekleştiren kişinin bununla istediği şekilde ilgilenmekten sorumlu olduğu anlamına gelir. Bunlardan, varsayılan davranış işlemi sonlandırmaktır. Ancak, varsayılan davranışı geçersiz kılabilir ve kendi işleyicimizi yazabiliriz. Aslında, birçok sinyal geçersiz kılınabilir ve Go geliştiricileri, sinyalin özel davranışını tanımlayabilecek kendi işleyicilerini yazabilir. Ancak, çok iyi bir sebep olmadıkça, sinyallerin varsayılan davranışını değiştirmek akıllıca bir fikir değildir.

Bir kenara, bu öğreticiyi bitirdikten sonra, go’da senkron ve asenkron işlevler hakkında daha fazla bilgi edinmek istiyorsanız, Go programlama eğitimini okumanızı öneririz: Go’da Eşzamanlılığa Giriş bilginizi ilerletmek için.

Okumak: Go’da Çöp Toplama Anlama

Go ve Golang’da Sinyalleri Kullanma Örneği

Go’da sinyallerin nasıl işlenebileceğini gösteren çok basit bir program aşağıdadır:

package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
)

func handler(signal os.Signal) {
	if signal == syscall.SIGTERM {
		fmt.Println("Got kill signal. ")
		fmt.Println("Program will terminate now.")
		os.Exit(0)
	} else if signal == syscall.SIGINT {
		fmt.Println("Got CTRL+C signal")
		fmt.Println("Closing.")
		os.Exit(0)
	} else {
		fmt.Println("Ignoring signal: ", signal)
	}
}

func main() {
	sigchnl := make(chan os.Signal, 1)
	signal.Notify(sigchnl)
	exitchnl := make(chan int)

	go func() {
		for {
			s := <-sigchnl
			handler(s)
		}
	}()

	exitcode := <-exitchnl
	os.Exit(exitcode)
}

Örnek Go kodumuzdaki program aşağıdaki adımlardan oluşmaktadır:

  • Git sinyali bildirimi gönderildiğinden beri os.Sinyal bir kanal üzerinden değerler, adlı kanalı oluşturduk işaret Bu, bildirimleri almanıza yardımcı olur.
  • Daha sonra verilen kanalı kullanarak kaydetmemiz gerekiyor. sinyal.Bildir() verilen kanal için bildirimleri almak için. Daha sonra gelen sinyali iletir. Programcılar, işlemek istedikleri gelen sinyalleri belirtebilir, örneğin sinyal.Bildir(sigchnl, sistem çağrısı.SIGTERM, sistem çağrısı.SIGINT). Sinyal verilmezse, gelen tüm sinyaller belirtilen kanala iletilir. Bu ilginçtir çünkü ayrı sinyallerle başa çıkmak için ayrı kanallara sahip ayrı işleyiciler yazabiliriz.
  • Ardından, bir goroutine olarak çalışan anonim bir işlev uygularız. Bu fonksiyonun içinde, tanımlı kullanıcıyı çağırmak için sonsuz bir döngü çalıştırıyoruz. işleyici işlev. için parametre işleyici fonksiyon tarafından belirtilen değerdir os.Sinyal arayüz.
  • adında başka bir kanal olduğunu unutmayın. çıkış Bu, programın çıkış kodu oluşturulana kadar beklemesini sağlamak için oluşturulur, aksi takdirde program basitçe yürütülür ve çıkar. Ancak aşağıdaki örnek kod ile de programı bekletebiliriz. çıkış kod:
for {
	time.Sleep(30 * time.Second)
}

Go Signal Hile Sayfası

İşte en iyi 15 Go sinyalinin bir kopya sayfası ve hızlı başvuru için ne anlama geldiklerini. Daha eksiksiz bir referans, signal(7)-Linux Kılavuz Sayfasında bulunabilir.

  • SIGHUP: ‘HUP’ = ‘kapattı’. Bu sinyal, kontrol terminalinde bir kontrol işlemi sona erdiğinde veya kapandığında üretilir.
  • İŞARET: Bir işlem klavyeden CTRL+C ile kesildiğinde
  • SIGQUIT: Klavyeden çık
  • SİGİL: Yasadışı talimat. eş anlamlısı SIGPWR() – güç kesintisi
  • SİGABRT: Program çağırır iptal() fonksiyon – acil durdurma.
  • SIGBUS: Kötü bellek erişimi. Belleğe uygun olmayan bir şekilde erişmeye çalışıldı
  • SIGFPE: FPE = Kayan nokta istisnası
  • SIGKILL: Öldürme sinyali. Süreç açıkça öldürüldü.
  • SIGUSR1: Bu sinyal, programcıların özel bir davranış yazması için açıktır.
  • SIGSEGV: Geçersiz bellek referansı. C’de dizi limitinin ötesinde belleğe erişmeye çalıştığımızda bu sinyal üretilir.
  • SIGUSR2: Bu sinyal, programcıların özel bir davranış yazması için açıktır.
  • SIGPIPE: Bu, programcıların özel bir davranış yazması için açık olduğumuzu gösterir.
  • SİGALRM: İşlem, işletim sistemi tarafından çağrılması gibi bir uyandırma çağrısı istedi. alarm() işlev.
  • SIGTERM: Bir süreç öldürüldü

Okumak: Go’da Hatalar Nasıl İşlenir?

Go’da Çoklu Sinyaller Nasıl İşlenir?

Go’da birden çok, ancak spesifik sinyalin nasıl ele alınacağını göstermek için yukarıdaki kodu biraz değiştirebiliriz:

package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
)

func multiSignalHandler(signal os.Signal) {

	switch signal {
	case syscall.SIGHUP:
		fmt.Println("Signal:", signal.String())
		os.Exit(0)
	case syscall.SIGINT:
		fmt.Println("Signal:", signal.String())
		os.Exit(0)
	case syscall.SIGTERM:
		fmt.Println("Signal:", signal.String())
		os.Exit(0)
	case syscall.SIGQUIT:
		fmt.Println("Signal:", signal.String())
		os.Exit(0)
	default:
		fmt.Println("Unhandled/unknown signal")
	}
}

func main() {
	sigchnl := make(chan os.Signal, 1)
	signal.Notify(sigchnl, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM) //we can add more sycalls.SIGQUIT etc.
	exitchnl := make(chan int)

	go func() {
		for {
			s := <-sigchnl
			multiSignalHandler(s)
		}
	}()

	exitcode := <-exitchnl
	os.Exit(exitcode)
}

Şimdi, kodu test etmek için iki terminal açın (Linux’ta). Bu programı şuradan çalıştırın: terminal 1 aşağıdaki komutla:

Terminal 1: go run main.go

git Terminal 2 ve bul PID (işlem kimliği) çalışan programın ana komutla:

$ ps -e. 

söyle, süreç kimliği 13014. O zaman koşuya belirli bir sinyal vermek isteriz. ana aşağıdaki programı kullanarak öldürmek emretmek:

$ kill -SIGHUP 13014

Bu, çalışan işlemi kapatacaktır terminal 1.

Ardından, çalıştırın ana.go tekrar ve başka bir sinyali test edin, örneğin öldür -SIGINT 13014. Kendinizi rahat hissedene kadar bu işlemi birkaç kez tekrarlayın. Nasıl yazılım üretebileceğimize dikkat edin (klavye – CTRL+C) gerçekten basmadan programlı olarak kesintiye uğrar CTRL+C.

Go ve Golang’da İşletim Sistemi Sinyalleri Üzerine Son Düşünceler

C’de sinyal işleme aslında çok yaygındır. Go’nun ayrıca bazı düşük seviyeli kodları işlemek için özellikler sağladığını görmek ilginçtir. Bu oldukça faydalı olabilir, çünkü geliştiriciler sinyalleri ele alırken veya kendi özel mesajlarını yazarken işleyici bir programı, diyelim ki bir sunucuyu zarafetle sonlandırmak veya herhangi bir işlemi düzgün bir şekilde sonlandırmak için bazı temizleme kodları yazabiliriz. CTRL+C basılır. Bu düşük seviyeli faydalar başka türlü mümkün değildir. Ancak, Go’nun C’nin yerini almak için tasarlanmadığını anlayın; C dili, sistem düzeyinde programlama söz konusu olduğunda üstündür ve öyle kalacaktır.

Devamını oku Go ve Golang programlama eğitimleri ve yazılım geliştirme kılavuzları.

İlgili Makaleler

Bir cevap yazın

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

Başa dön tuşu