2015-06-04 7 views
7

Rozumiem, że w Go, runtime.LockOSThread() będzie wiązał goroutine do jednego wątku systemu operacyjnego i nie pozwala na uruchamianie innych goroutines w tym wątku. Czy dotyczy to również dzieci goroutines?Czy plik runtime.LockOSThread umożliwia uruchamianie podrzędnych elementów potomnych w tym samym wątku systemu operacyjnego?

Na przykład:

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

Czy oba te goroutines wykonać w jednym wątku i wyłącznej OS lub tylko pierwszy z nich?

+1

Nie musisz podawać treści odpowiedzi na swoje pytanie w pytaniu, po prostu [oznacz jako zaakceptowane] (http://meta.stackexchange.com/a/5235/168708). – thwd

+0

Mimo że nie jest on obecnie obsługiwany, został [zaproponowano] (https://groups.google.com/d/msg/golang-dev/HJcGESXfJfs/X-SBuDkcBwAJ) dla nowej opcji opcjonalnej. I zaproponowałem [inne przypadki użycia] (https://stackoverflow.com/questions/1880262/forcing-goroutines-into-verame-thame#comment83771359_1928637). –

Odpowiedz

4

The documentation dla runtime.LockOSThread mówi:

LockOSThread przewody goroutine powołanie do jego aktualnego wątku systemu operacyjnego. Dopóki wywołująca goroutine nie wyjdzie lub nie zadzwoni do UnlockOSThread, zawsze będzie wykonywana w tym wątku, i żadna inna goroutine nie może.

(Kopalnia nacisk)

Oznacza to, że jeśli pewna realizacja idź zrobił co prosisz, byłoby błędne.

Aby wyjaśnić: jeśli goroutine zarezerwował wątek i inną goryntynę wykonaną na tej samej nitce; to byłoby złe.

+0

Używam wersji 1.4. Uruchomiłem przykład (teraz wymazałem) wiele razy i jest zgodny z moim wnioskiem. Jeśli implementacja jest niezgodna z dokumentacją, zgadzam się. Ale nie widzę żadnej korzyści blokowania pojedynczego rutowania do jednego wątku systemu operacyjnego, jeśli nie można odradzać więcej kontrolowanych goroutinów w tym wątku. – joaonrb

+0

Może 'runtime.NumCPU()' zwraca 1 w systemie? W każdym razie powinieneś zgłosić ten błąd, w tym repro. – thwd

+0

Używam 'runtime.GOMAXPROCS (runtime.NumCPU())'. Zgłoszę błąd. Ale uważam, że błąd występuje w dokumentacji, ponieważ nie rozumiem korzyści zablokowania goroutine do wątku systemu operacyjnego, jeśli nie pozwalasz na współbieżność.Nawet jej użycie nie jest jasne w dokumencie i może zostać źle zinterpretowane. Blokuje następną goroutine stworzoną do wątku systemu operacyjnego lub bieżącą? w ogóle nie jest jasne. – joaonrb

3

Możemy to sprawdzić za pomocą pthread.h na 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 
} 

Na moim komputerze drukuje coś takiego, main i locked zawsze jest czasami ten sam, ale czasami inaczej:

main 139711253194560 
locked 139711219787520 
locked child 139711236572928 

EDIT Zapomniałem o GOMAXPROCS. Dodano, wyniki są teraz różne.

+0

Dziękuję. Eksperymentuję twój przykład kładąc blokadę przed pierwszym przejściem i działa dobrze. Możesz dodać ten przykład do swojej odpowiedzi lub pozwolić mi na replikację twojego przykładu, aby odpowiedzieć na moje własne pytanie. – joaonrb

+0

@joaonrb Na początku zapomniałem o ustawieniu GOMAXPROCS. Edytowałem to teraz. –

+0

Okazuje się, że używałem runtime.LockOSThread() do późnego kodu. Użyłem twojego przykładu, aby wyjaśnić rozwiązanie mojego problemu. Dzięki. – joaonrb

Powiązane problemy