Menu
Coddy logo textTech

Grundlagen der Goroutines

Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy. Lektion 59 von 107.

Eine Goroutine ist ein leichtgewichtiger Ausführungs-Thread, der von der Go-Laufzeitumgebung verwaltet wird. Im Gegensatz zu herkömmlichen Threads, die erheblichen Speicher verbrauchen, starten Goroutines mit nur wenigen Kilobyte Stack-Speicher, sodass du Tausende davon gleichzeitig ausführen kannst.

Um eine Goroutine zu starten, setze einfach das Schlüsselwort go vor einen Funktionsaufruf:

func sayHello(name string) {
    fmt.Println("Hello,", name)
}

func main() {
    go sayHello("Alice")  // läuft gleichzeitig
    go sayHello("Bob")    // läuft gleichzeitig
    
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Done")
}

Wenn go sayHello("Alice") ausgeführt wird, wartet es nicht darauf, dass sayHello fertig wird. Stattdessen fährt es sofort mit der nächsten Zeile fort, während sayHello im Hintergrund ausgeführt wird. Deshalb benötigen wir time.Sleep; ohne dieses würde main beendet werden, bevor die Goroutinen abgeschlossen sind.

Du kannst Goroutines auch mit anonymen Funktionen starten:

go func(msg string) {
    fmt.Println(msg)
}("Hello from goroutine")

Die Hauptfunktion selbst wird in einer Goroutine ausgeführt. Wenn sie zurückkehrt, werden alle anderen Goroutines sofort beendet. Sie bekommen keine Gelegenheit, fertig zu werden. Die Verwendung von time.Sleep ist eine vorübergehende Lösung; in den kommenden Lektionen lernst du richtige Synchronisierungstechniken mit Channels und Wait Groups kennen.

challenge icon

Aufgabe

Einfach

Erstellen wir einen Task-Runner, der mehrere Tasks gleichzeitig mithilfe von Goroutines ausführt. Du erstellst ein einfaches System, in dem Tasks im Hintergrund ausgeführt werden, während das Hauptprogramm fortfährt, und demonstrierst damit, wie Goroutines eine nebenläufige Ausführung ermöglichen.

Du wirst deinen Code auf zwei Dateien verteilen:

  • tasks.go: Definiere hier die Logik zur Task-Ausführung.

    Erstelle eine Task-Struktur mit den Feldern Name (string) und Duration (int, repräsentiert Millisekunden).

    Implementiere eine Methode Run() für Task, die Arbeit simuliert, indem sie für die Dauer des Tasks wartet und anschließend Folgendes ausgibt: Task [Name] completed

    Erstelle eine Funktion RunAllTasks(tasks []Task), die die Methode Run() jedes Tasks als Goroutine startet. Nachdem alle Goroutines gestartet wurden, soll sie 500 Millisekunden warten, damit diese abgeschlossen werden können, und anschließend Folgendes ausgeben: All tasks launched

  • main.go: Lies die Task-Informationen ein und koordiniere die nebenläufige Ausführung.

    Lies die Anzahl der Tasks ein und anschließend den Namen und die Dauer jedes Tasks. Erstelle die Tasks und übergib sie an RunAllTasks. Gib nach der Rückkehr Folgendes aus: Main function done

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Anzahl der Tasks (Ganzzahl)
  • Folgende Zeilen: Für jeden Task zwei Zeilen – zuerst der Task-Name, dann seine Dauer in Millisekunden

Zum Beispiel bei folgender Eingabe:

3
Download
100
Process
50
Upload
75

Deine Ausgabe sollte die abgeschlossenen Tasks anzeigen (die Reihenfolge kann aufgrund der Nebenläufigkeit variieren), gefolgt von den Abschlussmeldungen:

Task Process completed
Task Upload completed
Task Download completed
All tasks launched
Main function done

Hinweis: Da Goroutines nebenläufig ausgeführt werden, werden Tasks mit kürzeren Dauern normalerweise zuerst abgeschlossen. Die Reihenfolge, in der die Tasks abgeschlossen werden, hängt von ihren Dauern ab – kürzere Tasks werden vor längeren abgeschlossen.

Verwende time.Sleep zusammen mit time.Duration und time.Millisecond für die Verzögerungen. Denke daran, dass die Funktion ohne die Wartezeit in RunAllTasks zurückkehren würde, bevor die Goroutines ihre Arbeit beendet haben.

Probier es selbst

package main

import (
	"fmt"
)

func main() {
	// Lies die Anzahl der Aufgaben
	var numTasks int
	fmt.Scanln(&numTasks)

	// TODO: Erstelle einen Slice, um die Aufgaben zu speichern
	
	// TODO: Lies Name und Dauer jeder Aufgabe
	// Für jede Aufgabe:
	//   - Lies den Aufgabennamen
	//   - Lies die Dauer (als Ganzzahl)
	//   - Erstelle eine Task und füge sie deinem Slice hinzu

	// TODO: Rufe RunAllTasks mit deinem tasks-Slice auf

	// TODO: Print "Main function done"
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Go-Compiler