La fonction main() est-elle une goroutine? Par exemple, j'ai vu une trace de pile de crash comme ci-dessous, ce qui me fait demander:

goroutine 1 [running]: main.binarySearch(0x0, 0x61, 0x43,
0xc420043e70, 0x19, 0x19, 0x10)
     /home/---/go/src/github.com/----/sumnum.go:22 +0x80 main.main()
     /home/---/go/src/github.com/---/sumnum.go:13 +0xc1 exit status 2
go
2
Manjeet Thakur 20 nov. 2018 à 10:28

3 réponses

Meilleure réponse

Oui, la fonction principale s'exécute dans une goroutine (la principale).

Selon https://tour.golang.org/concurrency/1

Un goroutine est un thread léger géré par le runtime Go. go f(x, y, z) démarre une nouvelle goroutine en cours d'exécution f(x, y, z) L'évaluation de f, x, y et z se produit dans la goroutine actuelle et l'exécution de f se produit dans la nouvelle goroutine .
Les goroutines s'exécutant dans le même espace d'adressage, l'accès à la mémoire partagée doit donc être synchronisé. Le package sync fournit des primitives utiles, bien que vous n'en ayez pas besoin beaucoup dans Go car il existe d'autres primitives.

Donc, selon ce document officiel, le main fonctionne dans la goroutine actuelle .


Maintenant, amusons-nous avec main et exécutons ceci (donc ici la goroutine actuelle exécute la nouvelle goroutine ), nous avons donc ici plus d'une goroutine qui exécutent à nouveau main()! (Remarque: l'accès à la mémoire partagée doit être synchronisé):

package main

import (
    "fmt"
    "time"
)

var i = 3

func main() {
    if i <= 0 {
        return
    }
    i--
    fmt.Println("Hi")
    go main()
    time.Sleep(100 * time.Millisecond)
}

Production:

Hi
Hi
Hi

Calculons factorielle en utilisant main() ( un goroutine - aucune synchronisation nécessaire):

package main

import "fmt"

func main() {
    if f <= 0 {
        fmt.Println(acc)
        return
    }
    acc *= f
    f--
    main()
}

var f = 5
var acc = 1

Production:

120

Remarque: les codes ci-dessus sont juste pour montrer clairement mes points de vue et ne sont pas bons pour une utilisation en production (l'utilisation de variables globales ne devrait pas être le premier choix).

5
wasmup 20 nov. 2018 à 15:37

La fonction principale est-elle une goroutine?

Non.

La fonction principale est une fonction.

En revanche,

Une goroutine est un fil d'exécution léger. (source).

Ainsi, les goroutines exécutent des fonctions, mais les goroutines ne sont pas des fonctions, et il n'y a pas de relation 1-à-1 entre les goroutines et les fonctions.

Pourtant...

La fonction main() est exécutée dans le premier (et au démarrage, uniquement) goroutine, goroutine #1.

Mais dès que cette fonction appelle une autre fonction, alors le goroutine principal n'exécute plus la fonction principale, et exécute à la place une autre fonction.

Il est donc clair qu'une goroutine et une fonction sont des entités entièrement différentes.

Ne confondez pas les goroutines avec les fonctions !!

Les fonctions et les goroutines sont des concepts entièrement différents. Et penser à eux comme la même chose entraînera d'innombrables confusions et problèmes.

8
Flimzy 20 nov. 2018 à 09:03

Oui. La fonction principale peut engendrer d'autres goroutines, mais "main" en elle-même est un groutine.

package main

import (
        "fmt"
        "runtime"
)

func main() {
        // Goroutine num includes main processing
        fmt.Println(runtime.NumGoroutine()) // 1

        // Spawn two goroutines
        go func() {}()
        go func() {}()

        // Total three goroutines run
        fmt.Println(runtime.NumGoroutine()) // 3
}
0
gede nata 27 janv. 2020 à 03:13