Als eine alberne grundlegende Threading Übung habe ich versucht, die sleeping barber problem in Golang zu implementieren. Mit Channels sollte das ganz einfach sein, aber ich bin auf einen Heisenbug gestoßen. Das heißt, wenn ich versuche, es zu diagnostizieren, verschwindet das Problem!Drucken auf stdout bewirkt, dass blockierte Goroutine ausgeführt wird?
Betrachten Sie Folgendes. Die main()
Funktion drückt Ganzzahlen (oder "Kunden") auf den Kanal shop
. barber()
liest den shop
Kanal, um "Kunden" Haare zu schneiden. Wenn ich eine fmt.Print
-Anweisung in die customer()
-Funktion einfügen, wird das Programm wie erwartet ausgeführt. Ansonsten schneidet barber()
niemals jemandes Haar.
package main
import "fmt"
func customer(id int, shop chan<- int) {
// Enter shop if seats available, otherwise leave
// fmt.Println("Uncomment this line and the program works")
if len(shop) < cap(shop) {
shop <- id
}
}
func barber(shop <-chan int) {
// Cut hair of anyone who enters the shop
for {
fmt.Println("Barber cuts hair of customer", <-shop)
}
}
func main() {
shop := make(chan int, 5) // five seats available
go barber(shop)
for i := 0; ; i++ {
customer(i, shop)
}
}
Eine Idee, was ist los?
Ihre Antwort gilt, wenn nur ein Thread von der go-Laufzeit verwendet wird. Wenn GOMAXPROCS entweder über einen Laufzeitaufruf gesetzt wird, wie es bei lazy1 der Fall ist, oder wenn die Umgebungsvariable gesetzt wird, kann jede goroutine parallel zu anderen goroutines in einem separaten Thread laufen. Es könnte sich lohnen, Ihre Antwort zu erweitern, um zu zeigen, wie die Laufzeit von go auf die verfügbaren Threads multiplext. –