Menu
Coddy logo textTech

Kanallar ve İletişim

Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 60 / 107.

Channels, Go'da goroutineler arasındaki iletişim için kullanılan temel mekanizmadır. Goroutineler belleği doğrudan paylaşmak yerine, Go'nun şu felsefesini izleyerek kanallar aracılığıyla değer gönderip alır: "Belleği paylaşarak iletişim kurma; iletişim kurarak belleği paylaş."

chan anahtar sözcüğüyle make işlevini kullanarak bir kanal oluşturun:

messages := make(chan string)

Değerleri göndermek ve almak için ok operatörünü <- kullanın. Ok, veri akışının yönünü gösterir:

func main() {
    messages := make(chan string)
    
    go func() {
        messages <- "hello"  // kanala gönder
    }()
    
    msg := <-messages  // kanaldan al
    fmt.Println(msg)   // Çıktı: hello
}

Varsayılan olarak, diğer taraf hazır olana kadar gönderme ve alma işlemleri bloklanır. Goroutine "hello" gönderdiğinde, main almaya hazır olana kadar bekler. Bu bloklama davranışı yerleşik senkronizasyon sağlar: time.Sleep gerekmez.

Daha fazla değer gönderilmeyeceğini belirtmek için bir kanalı kapatabilirsiniz. Alıcılar bunu algılayabilir:

close(messages)

msg, ok := <-messages
if !ok {
    fmt.Println("Channel closed")
}

Kanallar türlere sahiptir: bir chan string yalnızca dizeler taşıyabilir. Bu tür güvenliği, goroutine'lerin doğru veri türleriyle iletişim kurmasını sağlar ve hataları çalışma zamanı yerine derleme zamanında yakalar.

challenge icon

Görev

Kolay

goroutine'ların channel'lar aracılığıyla nasıl iletişim kurduğunu gösteren bir message relay sistemi oluşturalım. message'ların farklı işleme aşamaları arasında aktığı ve her aşamanın eşzamanlı olarak çalıştığı bir pipeline oluşturacaksın.

kodunu iki dosya arasında düzenleyeceksin:

  • relay.go: message işleme pipeline'ını tanımla.

    ID (int) ve Content (string) fields'larına sahip bir Message struct'ı oluştur.

    Pipeline'ının farklı aşamalarını temsil eden üç function uygula:

    • Producer(messages []Message, out chan Message) - Bir message dilimi alır ve her birini output channel'ına gönderir. Tüm message'ları gönderdikten sonra tamamlanmayı bildirmek için channel'ı kapat.
    • Transformer(in chan Message, out chan Message) - Input channel'ından message'ları alır, her message'ın content'ini büyük harfe dönüştürür ve dönüştürülen message'ı output channel'ına gönderir. Input channel kapatıldığında (iki değerli alma biçimi kullanılarak algılanır) output channel'ını kapat.
    • Consumer(in chan Message) []string - Input channel'ından tüm message'ları alır ve bunları biçimlendirilmiş string'lerden oluşan bir dilimde collect eder. Her string şu formatı izlemelidir: Message [ID]: [Content]. Channel kapatıldığında dilimi döndür.
  • main.go: Pipeline'ı kur ve eşzamanlı message akışını yönet.

    message sayısını oku, ardından her message'ın ID'sini ve content'ini oku. Message'ları oluştur ve üç pipeline aşamanı birbirine bağlamak için iki channel kur. Producer ve Transformer'ı goroutine olarak başlat, ardından sonuçları collect etmek için Consumer'ı main goroutine'inde çalıştır. Her sonucu ayrı bir line'a yazdır.

Aşağıdaki input'lar sağlanacaktır:

  • Line 1: Message sayısı (integer)
  • Sonraki line'lar: Her message için iki line - message ID'si (integer), ardından content'i (string)

Örneğin, şu verilirse:

2
1
hello world
2
go channels

Output'un şu şekilde olmalıdır:

Message 1: HELLO WORLD
Message 2: GO CHANNELS

Pipeline şu şekilde akar: Producer message'ları gönderir → Transformer büyük harfe converts eder → Consumer sonuçları collect eder ve biçimlendirir. Her ok, eşzamanlı aşamaları birbirine bağlayan bir channel'ı temsil eder. Büyük harfe dönüştürme için strings package'ını kullan.

Kendin dene

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Mesaj sayısını oku
	nLine, _ := reader.ReadString('\n')
	n, _ := strconv.Atoi(strings.TrimSpace(nLine))

	// Mesajları oku
	messages := make([]Message, n)
	for i := 0; i < n; i++ {
		idLine, _ := reader.ReadString('\n')
		id, _ := strconv.Atoi(strings.TrimSpace(idLine))
		contentLine, _ := reader.ReadString('\n')
		content := strings.TrimSpace(contentLine)
		messages[i] = Message{ID: id, Content: content}
	}

	// TODO: Pipeline aşamalarını bağlamak için iki kanal oluştur

	// TODO: Producer'ı bir goroutine olarak başlat

	// TODO: Transformer'ı bir goroutine olarak başlat

	// TODO: Consumer'ı ana goroutine'de çalıştır ve sonuçları topla

	// TODO: Her sonucu ayrı bir satıra yazdır
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Go derleyicisi