2009-11-16 16 views

Odpowiedz

23

Cytat z Day 3 Tutorial < - przeczytaj ten artykuł, aby uzyskać więcej informacji.

Gorulenki są multipleksowane według potrzeb na wątki systemowe. Kiedy goroutine wykonuje blokujące wywołanie systemowe, inna goroutyna jest zablokowana.

Będziemy robić to samo dla CPU-bound goroutines w pewnym momencie, ale teraz, jeśli chcesz poziomie użytkownika równoległość ty musi ustawić $ GOMAXPROCS. lub zadzwoń pod numer runtime.GOMAXPROCS (n).

Goroutine niekoniecznie odpowiada wątkowi systemu operacyjnego. Może mieć mniejszy początkowy rozmiar stosu, a stos będzie wzrastał w miarę potrzeb.

W razie potrzeby wiele gorouitin może zostać zmultipleksowanych w jeden wątek.

Co ważniejsze, koncepcja jest taka, jak opisano powyżej, że goroutine jest programem sekwencyjnym, który może blokować się, ale nie blokuje innych goroutines.

Goroutines jest zaimplementowany jako pthreads w gccgo, więc może być identyczny z wątkiem systemu operacyjnego. Oddziela pojęcie wątku systemu operacyjnego od myślenia o wielowątkowości podczas programowania.

+0

Przerwany link do samouczka - wygląda jak http://go.googlecode.com/hg-history/release-branch.r60/doc/GoCourseDay3.pdf może być to. – I82Much

13

IMO, co sprawia, że ​​wielowątkowość w Go jest atrakcyjna, to możliwości komunikacyjne: w przeciwieństwie do pthread, gdzie trzeba zbudować infrastrukturę komunikacyjną (mutex, kolejki itp.), W Go jest ona domyślnie dostępna w wygodnej formie.

W skrócie, istnieje "niskie tarcie" na używanie nici z powodu dobrej komunikacji obiektów (podobnie jak Erlang, jeśli mogę tak powiedzieć).

14

W kompilatorach wzorcowych (5g/6g/8g) główny program planujący (src/pkg/runtime/proc.c) tworzy wątki N OS, gdzie N jest kontrolowane przez runtime.GOMAXPROCS (n) (domyślnie 1). Każdy wątek harmonogramu ściąga nową goroutine z głównej listy i uruchamia ją. Goroutine (s) będzie działało, dopóki nie zostanie utworzona syscall (np. Printf) lub zostanie wykonana operacja na kanale, w którym to momencie planista chwyci następną goroutine i uruchamia ją od miejsca, w którym ją przerwał (patrz wywołania gosched() w src/pkg/runtime/chan.c).

Harmonogram, we wszystkich celach i celach, jest realizowany za pomocą coroutines. Ta sama funkcja może być napisana prostym C przy użyciu setjmp() i longjmp(), Go (i innych języków, które implementują lekkie/zielone wątki) po prostu automatyzują proces dla ciebie.

Zaletą lekkich wątków jest to, że jest to cała przestrzeń użytkownika, tworzenie "wątku" jest bardzo tanie (przydzielanie niewielkiego domyślnego stosu) i może być bardzo wydajne ze względu na nieodłączną strukturę tego, jak wątki ze sobą rozmawiają. Minusem jest to, że nie są prawdziwymi wątkami, co oznacza, że ​​pojedynczy lekki wątek może zablokować cały program, nawet jeśli wydaje się, że wszystkie wątki powinny działać jednocześnie.

+0

Czy wprowadzono aktualizację do tej implementacji od czasu odpowiedzi? – Curious

+1

proc.c już nie istnieje, ponieważ wygląda na to, że kompilator Go jest teraz hostem własnym: https://golang.org/src/runtime/proc.go – Michaelangel007

4

Jak stwierdziły poprzednich odpowiedzi, przejdź rutyny może różnić się do wątków systemowych jednak znalazłem następujące przydatna, jeśli trzeba mieć wzrost wydajności wielowątkowości teraz:

Obecna implementacja Środowisko wykonawcze Go nie będzie domyślnie porównywać tego kodu z. Dedykuje tylko jeden rdzeń do przetwarzania na poziomie użytkownika. Dowolna liczba goroutin może zostać zablokowana w wywołaniach systemowych, ale domyślnie tylko jeden może w dowolnym momencie wykonać kod na poziomie użytkownika. To powinno być mądrzejsze i pewnego dnia będzie mądrzejszy, ale dopóki nie jest to , jeśli chcesz równoległości procesora, musisz powiedzieć run-time ile głupków chcesz jednocześnie wykonać kod. Istnieją dwa powiązane sposoby, aby to zrobić. Albo uruchom swoją pracę ze zmienną środowiskową GOMAXPROCS ustawioną na liczbę rdzeni do użycia lub zaimportowania pakietu środowiska wykonawczego i wywołania runtime.GOMAXPROCS (NCPU). Pomocną wartością może być runtime.NumCPU(), która zgłasza liczbę procesorów logicznych na komputerze lokalnym. Ponownie oczekuje się, że wymóg ten zostanie wycofany, gdy harmonogram i czas pracy ulegną poprawie.

quote source

Przykładowy program, który maxes mój procesor i5 jest to (wykorzystuje wszystkie 4 rdzenie na 100% w htop):

package main 


import (
    "fmt" 
    "time" 
    "runtime" 
) 


func main() { 
    runtime.GOMAXPROCS(4) // Set the maximum number of threads/processes 

    d := make(chan string) 
    go boring("boring!", d, 1) 
    go boring("boring!", d, 2) 
    go boring("boring!", d, 3) 
    go boring("boring!", d, 4) 

    for i := 0; i < 10; i++ { 
     time.Sleep(time.Second); 
    } 

    fmt.Println("You're boring; I'm leaving.") 
} 

func boring(msg string, c chan string, id int) { 
    for i := 0; ; i++ { 

    } 
} 

Teraz, gdy w rzeczywistości nie 'zrobić' cokolwiek, ale zobacz, jak krótkie/łatwe/proste, w porównaniu do pisania wielowątkowych aplikacji w innych językach, takich jak Java.

Powiązane problemy