Go

2015-03-10 27 views
6

'da goroutine bir çıktı yok SayHello() beklendiği gibi yürütülürken, goroutine hiçbir şey basmıyor.Go

package main 

import "fmt" 

func SayHello() { 
    for i := 0; i < 10 ; i++ { 
     fmt.Print(i, " ") 
    } 
} 

func main() { 
    SayHello() 
    go SayHello() 
} 
+0

olası yinelenen gibi ayrı rutin her baskı deyimi aynı anda sayıları yazdırmak çalıştırmak için

package main import ( "fmt" "sync" ) func SayHello() { for i := 0; i < 10; i++ { fmt.Print(i, " ") } } func main() { SayHello() var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() SayHello() }() wg.Wait() } 

([time.sleep dahil eğer Goroutine yürütmüyor] http: // stackoverflow. com/questions/28307783/goroutine-does-not-execute-if-time-sleep-included) –

cevap

15

main() işleviniz bittiğinde, programınız da sona erer. Diğer goroutines'in bitmesini beklemez.

Go Language Specification: Program Execution alıntı:

Programı yürütme fonksiyonunu main yürütmesini sonra ana paket başlatılıyor ve başlar. Bu işlev çağrısı döndüğünde, program çıkar. Diğer (main) goroutines'in tamamlanmasını beklemez.

Daha fazla ayrıntı için this answer adresine bakın.

işlevinin tamamlanmasının bir goroutin olarak başlatılmasını beklemek için main() işlevinizi bildirmeniz gerekir. Örneğin kanalların senkronize edebilirsiniz:

func SayHello(done chan int) { 
    for i := 0; i < 10; i++ { 
     fmt.Print(i, " ") 
    } 
    if done != nil { 
     done <- 0 // Signal that we're done 
    } 
} 

func main() { 
    SayHello(nil) // Passing nil: we don't want notification here 
    done := make(chan int) 
    go SayHello(done) 
    <-done // Wait until done signal arrives 
} 

diğer alternatif kanalını kapatarak tamamlandığının belirtilmesi için geçerli:

func SayHello(done chan struct{}) { 
    for i := 0; i < 10; i++ { 
     fmt.Print(i, " ") 
    } 
    if done != nil { 
     close(done) // Signal that we're done 
    } 
} 

func main() { 
    SayHello(nil) // Passing nil: we don't want notification here 
    done := make(chan struct{}) 
    go SayHello(done) 
    <-done // A receive from a closed channel returns the zero value immediately 
} 

Notlar:

yaptığınız düzenlemeler/yorumların göre: SayHello()'un çalıştırılması işlevinin "karışık" sayıları rasgele yazdırmasını istiyorsanız: bu tür davranışları gözlemleme garantisi yoktur. Tekrar, daha fazla ayrıntı için aforementioned answer'a bakın. Go Memory Model sadece belirli olayların diğer etkinliklerden önce gerçekleştiğini garanti eder, aynı anda 2 eş zamanlı rutinin nasıl yürütüldüğünü garanti etmezsiniz.

Bununla deney yapabilirsiniz, ancak sonucun deterministik olmayacağını bilin. Önce birlikte yürütülecek birden çok etkin goroutines etkinleştirmek zorunda:

runtime.GOMAXPROCS(2) 

İkincisi, geçerli kod ilk ana goroutine içinde SayHello() yürütür ve yalnızca bitmiş bir kez diğer başlar çünkü öncelikle bir goroutine olarak SayHello() başlamak zorunda tek:

runtime.GOMAXPROCS(2) 
done := make(chan struct{}) 
go SayHello(done) // FIRST START goroutine 
SayHello(nil) // And then call SayHello() in the main goroutine 
<-done // Wait for completion 
+1

Doğru, sadece http://dave.cheney.net/2014/03/19/channel- aksiyomlar: Sonsuza kadar bir "nil" kanalına gönderilirse, A bir "nil" kanalından sonsuza dek bir blok alır. – VonC

+0

@icza lütfen düzenlemeleri kontrol edin. –

+0

@DineshPanchananam "Tekdüze" moda ile ne demek istiyorsun? Karışık sayıları rastgele çalışan 2 SayHello() işlevinden görmeyi mi bekliyorsunuz? – icza

5

Alternatif (icza cevabı) orijinal SayHello değiştirilmesini engellemek sync paket ve anonim işlevinden WaitGroup kullanabilirsiniz. Aşağıdaki

package main 

import (
    "fmt" 
    "math/rand" 
    "sync" 
    "time" 
) 

func main() { 
    var wg sync.WaitGroup 

    for i := 0; i < 10; i++ { 
     wg.Add(1) 
     go func(fnScopeI int) { 
      defer wg.Done() 

      // next two strings are here just to show routines work simultaneously 
      amt := time.Duration(rand.Intn(250)) 
      time.Sleep(time.Millisecond * amt) 

      fmt.Print(fnScopeI, " ") 
     }(i) 
    } 

    wg.Wait() 
} 
+0

Lütfen düzenlemeleri kontrol edin –

+0

@DineshPanchananam Her bir sayıyı ayrı bir rutinde yazdırmak ister misiniz? – Sundrique

+0

Hayır. "" Paralel "" bir şey bekleniyor. "Ama sanırım yanıldım. –