2015-06-04 14 views
7

Capisco che in Go, runtime.LockOSThread() si associ una goroutine a un thread del sistema operativo e non si consenta l'esecuzione di altre goroutine in tale thread. Questo vale anche per le goroutine infantili?Il runtime.Lockouthread consente ai goroutini figli di essere eseguiti nello stesso thread del sistema operativo?

Ad esempio:

runtime.LockOSThread() 
go func() { 
    go func() { 
     // Do something 
    }() 
    // Do something 
}() 

fare entrambe queste goroutines eseguire in un unico ed esclusivo filo OS o solo il primo?

+1

Non è necessario includere il corpo della risposta alla domanda nella domanda, solo [contrassegnarlo come accettato] (http://meta.stackexchange.com/a/5235/168708). – thwd

+0

Anche se non è attualmente supportato, è stato [proposto] (https://groups.google.com/d/msg/golang-dev/HJcGESXfJfs/X-SBuDkcBwAJ) per una nuova funzionalità opzionale. E ho proposto [altri casi d'uso] (https://stackoverflow.com/questions/1880262/forcing-goroutines-into-the-same-thread#comment83771359_1928637). –

risposta

4

The documentation per runtime.LockOSThread dice:

fili LockOSThread la chiamata goroutine al suo attuale thread di sistema operativo. Fino a quando la goroutine di chiamata non si chiude o chiama Unlockisthread, verrà sempre eseguito in tale thread, e nessun'altra goroutine può.

(sottolineatura mia)

Ciò significa che se una certa implementazione di Go ha fatto quello che stai chiedendo, sarebbe difettosa.

Per chiarire: se una goroutine aveva prenotato un filo e un'altra goroutine eseguita su quella stessa filettatura; è quello che sarebbe sbagliato.

+0

Sto usando la versione 1.4. Ho eseguito l'esempio (ora cancellato) più volte ed è coerente con la mia conclusione. Se l'implementazione è incoerente con la documentazione, sono d'accordo. Ma non vedo alcun vantaggio nel bloccare una singola routine su un thread del sistema operativo se non è possibile generare goreutine più controllate in quel thread. – joaonrb

+0

Forse 'runtime.NumCPU()' restituisce 1 sul tuo sistema? In ogni caso dovresti segnalare questo bug, inclusa la riproduzione. – thwd

+0

Sto usando 'runtime.GOMAXPROCS (runtime.NumCPU())'. Segnalerò il bug. Ma credo che l'errore sia nella documentazione perché non riesco a capire i vantaggi di bloccare una goroutine su un thread del sistema operativo se non si consente la concorrenza interna.Anche se l'uso non è chiaro in doc e può essere male interpretato. Blocca la successiva goroutine creata sul thread del sistema operativo o quella corrente? non è affatto chiaro. – joaonrb

3

Possiamo controllare utilizzando del pthread.h pthread_self:

package main 

// #include <pthread.h> 
import "C" 
import (
    "fmt" 
    "runtime" 
) 

func main() { 
    runtime.GOMAXPROCS(runtime.NumCPU()) 
    ch1 := make(chan bool) 
    ch2 := make(chan bool) 
    fmt.Println("main", C.pthread_self()) 
    go func() { 
     runtime.LockOSThread() 
     fmt.Println("locked", C.pthread_self()) 
     go func() { 
      fmt.Println("locked child", C.pthread_self()) 
      ch1 <- true 
     }() 
     ch2 <- true 
    }() 
    <-ch1 
    <-ch2 
} 

Sulla mia macchina viene stampato qualcosa del genere, e mainlocked sempre di essere a volte lo stesso, ma a volte diversa:

main 139711253194560 
locked 139711219787520 
locked child 139711236572928 

EDIT Ho dimenticato GOMAXPROCS. Aggiunto, i risultati sono diversi ora.

+0

Grazie. Sperimento il tuo esempio mettendo il lucchetto prima del primo tentativo e funziona perfettamente. Puoi aggiungere quell'esempio alla tua risposta o permettermi di replicare il tuo esempio per rispondere alla mia stessa domanda. – joaonrb

+0

@joaonrb All'inizio mi sono dimenticato di impostare GOMAXPROCS. L'ho modificato ora. –

+0

Si scopre che stavo usando il runtime.LockOSThread() fino a tardi nel codice. Ho usato il tuo esempio per spiegare la soluzione al mio problema. Grazie. – joaonrb

Problemi correlati