2009-11-16 13 views

risposta

23

Citato da Day 3 Tutorial < - leggere questo per ulteriori informazioni.

Le goroutine sono multiplexate secondo le necessità sulle discussioni di sistema. Quando una goroutine esegue una chiamata di sistema di blocco, nessuna altra goroutine è bloccata.

noi faremo lo stesso per CPU-bound goroutines a un certo punto, ma per ora, se si desidera a livello di utente parallelismo si necessario impostare $ GOMAXPROCS. oppure chiamare il runtime.GOMAXPROCS (n).

Una goroutine non corrisponde necessariamente a un thread del sistema operativo. Può avere dimensioni di stack iniziali più piccole e lo stack crescerà in base alle esigenze.

gorouitines multiple possono essere multiplati in un unico filo quando necessario.

Ancora più importante, il concetto è come descritto sopra, che una goroutine è un programma sequenziale che può bloccarsi ma non blocca altri goroutines.

Goroutines è implementato come pthreads in gccgo, quindi può essere identico al filo OS, anche. Separa il concetto di thread del sistema operativo e il nostro modo di pensare al multithreading durante la programmazione.

+0

Collegamento interrotto all'esercitazione: simile a http://go.googlecode.com/hg-history/release-branch.r60/doc/GoCourseDay3.pdf potrebbe esserlo. – I82Much

13

IMO, ciò che rende appetibile la multi-threading in Go è la facilità di comunicazione: diversamente da pthread in cui si deve costruire l'infrastruttura di comunicazione (mutex, code ecc.), In Go è disponibile di default in una comoda forma.

In breve, c'è "low-friction" per l'utilizzo di thread a causa della buona comunicazione strutture (simile a Erlang se posso dire così).

14

Nei compilatori di riferimento (5 g/6 g/8 g), lo schedulatore principale (src/pkg/runtime/proc.c) crea i thread del sistema operativo, dove N è controllato dal runtime. GOMAXPROCS (n) (valore predefinito 1). Ogni thread di pianificazione estrae una nuova goroutine dall'elenco principale e inizia a eseguirla. Le goroutine continueranno a funzionare fino a quando non viene creato un syscall (ad esempio printf) o un'operazione su un canale, a quel punto lo scheduler afferra la successiva goroutine ed eseguila dal punto in cui era stata interrotta (vedere gosched() chiama in src/pkg/runtime/chan.c).

La programmazione, per tutti gli effetti, è implementato con coroutines. La stessa funzionalità potrebbe essere scritta in C rettilineo usando setjmp() e longjmp(), Go (e altri linguaggi che implementano thread leggeri/verdi) stanno solo automatizzando il processo per te.

L'aspetto positivo dei thread leggeri è dato dal fatto che è tutto spazio utente, la creazione di un "thread" è molto economico (allocando un piccolo stack predefinito) e può essere molto efficiente a causa della struttura intrinseca di come i thread parlano tra loro. Lo svantaggio è che non sono thread veri, il che significa che un singolo thread leggero può bloccare l'intero programma, anche quando sembra che tutti i thread debbano essere eseguiti contemporaneamente.

+0

Sono stati apportati aggiornamenti a questa implementazione dal momento in cui hai risposto a questa domanda? – Curious

+1

proc.c non esiste più in quanto sembra che il compilatore Go sia ora auto hosting: https://golang.org/src/runtime/proc.go – Michaelangel007

4

Come risposte precedenti hanno già detto, andare routine non corrispondono necessariamente alle discussioni sistema però ho trovato il seguente utile se si deve avere l'incremento di prestazioni del multi-threading in questo momento:

L'implementazione corrente di il runtime Go non esegue parallelamente il codice per impostazione predefinita. Dedica solo un singolo core all'elaborazione a livello di utente. Un numero arbitrario di goroutine può essere bloccato nelle chiamate di sistema, ma per impostazione predefinita solo uno può eseguire codice a livello utente in qualsiasi momento. Dovrebbe essere più intelligente e un giorno sarà più intelligente, ma fino a quando non è se si desidera il parallelismo della CPU è necessario dire al tempo di esecuzione quante goroutine si desidera eseguire codice contemporaneamente. Ci sono due modi per farlo. Esegui il tuo lavoro con la variabile di ambiente GOMAXPROCS impostata sul numero di core da utilizzare o importare il pacchetto di runtime e chiamare runtime.GOMAXPROCS (NCPU). Un valore utile potrebbe essere runtime.NumCPU(), che segnala il numero di CPU logiche sul computer locale. Anche in questo caso, questo requisito dovrebbe essere ritirato poiché la pianificazione e il tempo di esecuzione migliorano.

quote source

un programma esempio che arriva al massimo il mio processore i5 è questo (usa tutti e 4 i core al 100% in 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++ { 

    } 
} 

Ora che in realtà non 'do' qualsiasi cosa, ma vedere quanto è breve/facile/semplice rispetto alla scrittura di applicazioni multithread in altri linguaggi come Java.

Problemi correlati