Menu
Coddy logo textTech

Goroutines Grundlagen

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

Eine Goroutine ist ein leichtgewichtiger Ausführungsthread, der von der Go-Runtime verwaltet wird. Im Gegensatz zu herkömmlichen Threads, die erheblichen Speicher verbrauchen, starten Goroutines mit nur wenigen Kilobyte Stack-Speicher, was es Ihnen ermöglicht, Tausende von ihnen gleichzeitig auszuführen.

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

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

func main() {
    go sayHello("Alice")  // wird gleichzeitig ausgeführt
    go sayHello("Bob")    // wird gleichzeitig ausgeführt
    
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Done")
}

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

Sie können Goroutinen auch mit anonymen Funktionen starten:

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

Die main-Funktion selbst läuft in einer Goroutine. Wenn sie beendet wird, werden alle anderen Goroutinen sofort abgebrochen – sie erhalten keine Gelegenheit, ihre Ausführung abzuschließen. Die Verwendung von time.Sleep ist eine vorübergehende Lösung; in den kommenden Lektionen werden Sie fortgeschrittene Synchronisationstechniken mit Channels und WaitGroups kennenlernen.

challenge icon

Aufgabe

Einfach

Lassen Sie uns einen Task-Runner bauen, der mehrere Aufgaben gleichzeitig mit Goroutinen ausführt. Sie erstellen ein einfaches System, bei dem Aufgaben im Hintergrund laufen, während das Hauptprogramm fortgesetzt wird, was demonstriert, wie Goroutinen eine nebenläufige Ausführung ermöglichen.

Sie werden Ihren Code auf zwei Dateien verteilen:

  • tasks.go: Definieren Sie Ihre Logik zur Aufgabenausführung.

    Erstellen Sie ein Task-Struct mit den Feldern Name (string) und Duration (int, repräsentiert Millisekunden).

    Implementieren Sie eine Methode Run() für Task, die Arbeit simuliert, indem sie für die Dauer der Aufgabe pausiert und dann ausgibt: Task [Name] completed

    Erstellen Sie eine Funktion RunAllTasks(tasks []Task), die die Run()-Methode jeder Aufgabe als Goroutine startet. Nach dem Starten aller Goroutinen sollte sie 500 Millisekunden lang pausieren, um deren Abschluss zu ermöglichen, und dann ausgeben: All tasks launched

  • main.go: Lesen Sie die Aufgabeninformationen ein und orchestrieren Sie die nebenläufige Ausführung.

    Lesen Sie die Anzahl der Aufgaben ein, und lesen Sie dann für jede Aufgabe den Namen und die Dauer. Erstellen Sie die Aufgaben und übergeben Sie diese an RunAllTasks. Nachdem die Funktion zurückkehrt, geben Sie aus: Main function done

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Anzahl der Aufgaben (Ganzzahl)
  • Folgende Zeilen: Für jede Aufgabe zwei Zeilen - der Aufgabenname, dann die Dauer in Millisekunden

Zum Beispiel, gegeben:

3
Download
100
Process
50
Upload
75

Ihre Ausgabe sollte den Abschluss der Aufgaben zeigen (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 Goroutinen gleichzeitig laufen, werden Aufgaben mit kürzerer Dauer normalerweise zuerst fertig. Die Reihenfolge des Aufgabenabschlusses hängt von deren Dauer ab - kürzere Aufgaben werden vor längeren abgeschlossen.

Verwenden Sie time.Sleep mit time.Duration und time.Millisecond für die Verzögerungen. Denken Sie daran, dass die Funktion ohne das Sleep in RunAllTasks zurückkehren würde, bevor die Goroutinen ihre Arbeit beendet haben.

Spickzettel

Eine Goroutine ist ein leichtgewichtiger Ausführungsthread, der von der Go-Runtime verwaltet wird. Goroutinen starten mit nur wenigen Kilobyte Stack-Speicher, was es ermöglicht, Tausende von ihnen gleichzeitig auszuführen.

Um eine Goroutine zu starten, setzen Sie das Schlüsselwort go vor einen Funktionsaufruf:

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

func main() {
    go sayHello("Alice")  // wird gleichzeitig ausgeführt
    go sayHello("Bob")    // wird gleichzeitig ausgeführt
    
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Done")
}

Wenn go sayHello("Alice") ausgeführt wird, wartet es nicht darauf, dass sayHello beendet wird. Stattdessen fährt es sofort mit der nächsten Zeile fort, während sayHello im Hintergrund läuft.

Sie können Goroutinen mit anonymen Funktionen starten:

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

Die main-Funktion selbst läuft in einer Goroutine. Wenn sie zurückkehrt, werden alle anderen Goroutinen sofort beendet. Verwenden Sie time.Sleep, um Goroutinen den Abschluss zu ermöglichen, bevor die main-Funktion beendet wird.

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 den Namen und die Dauer jeder Aufgabe
	// Für jede Aufgabe:
	//   - Lies den Aufgabennamen
	//   - Lies die Dauer (als Ganzzahl)
	//   - Erstelle eine Task und hänge sie an deinen Slice an

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

	// TODO: Gib "Main function done" aus
}
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