2016-03-31 19 views
0

"Eat", "Work", "Sleep", sırasıyla her 3., 8. ve 24. saniye basan bir program oluşturmaya çalışıyorum.Golang: Olmaması gereken deyimleri çıkar

package main 

import (
"fmt" 
"time" 
) 

func Remind(text string, delay time.Duration) <-chan string { //channel only for receiving strings 
    ch := make(chan string) // buffered/unbuffered? 
    go func() { 
     for { 
      msg := "The time is " + time.Now().Format("2006-01-02 15:04:05 ") + text 
      ch <- msg 
      time.Sleep(delay) // waits according to specification 
     } 
    }() 
    return ch 
} 

func main() { 
    ch1 := Remind("Eat", 1000*1000*1000*3) // every third second  
    ch2 := Remind("Work", 1000*1000*1000*8) // every eighth second 
    ch3 := Remind("Sleep", 1000*1000*1000*24) // every 24th second 
    select { // chooses one channel that is not empty. Should run forever (?) 
     case rem1 := <-ch1: 
      fmt.Println(rem1) 
     case rem2 := <-ch2: 
      fmt.Println(rem2) 
     case rem3 := <-ch3: 
      fmt.Println(rem3) 
    } 
} 

onunla sorun "Eat" ardından vakit yazdırmadan hemen sonra çalışmasını durdurur şudur: İşte benim kodudur. Okudum diğer örneklerde, select ifade sonsuza kadar devam ediyor. Neden şimdi değil? Eğer select okumuştum

cevap

2

bilmiyorum sonsuza kadar gider, ama öyle değil. Bir case idam edildikten sonra

, select açıklamada "bitti" dir. case s belirtilen iletişim operasyonların hiçbiri ilerleyebilir ve hiçbir default şube varsa, select sürece com herhangi olduğunca engeller. Ops devam edebilir. Ancak, bir case yürütüldüğünde, select tekrarlanmaz.

İlgili bölümü şu makaleden okuyun: Select statements.

for { 
    select { // chooses one channel that is not empty. Should run forever (?) 
    case rem1 := <-ch1: 
     fmt.Println(rem1) 
    case rem2 := <-ch2: 
     fmt.Println(rem2) 
    case rem3 := <-ch3: 
     fmt.Println(rem3) 
    } 
} 

Bir not olarak:

Sen time paketinden sabitleri kullanılarak, time.Duration değerleri çok daha kolay oluşturabilirsiniz:

sonsuz for içinde

koyun onu sonsuza kadar tekrarlamak yapmak

ch1 := Remind("Eat", 3*time.Second) // every third second 
ch2 := Remind("Work", 8*time.Second) // every eighth second 
ch3 := Remind("Sleep", 24*time.Second) // every 24th second 

Ayrıcakontrol etmek isteyebilirsiniz Remind() işlevinize benzer görevler içintürü. Git

+0

sonra bir şeyler yanlış olmalı. Teşekkürler! – Sahand

+0

@Sandi Büyük olasılıkla 'select', iletişim işlemleri gerekmediği takdirde, gerekirse devam ederse bekler. Ama tekrar etmez. – icza

+0

Yani, örneğin, tüm kanallar boşsa, 'select' bekleyecek mi? – Sahand

2

select çoğunlukla anahtarı kontrol deyimi benzer ve bazen iletişim anahtarı denir. select, kanallardaki gelen verileri dinler, ancak bir kanalda bir değerin gönderildiği durumlar da olabilir. Tek bir kelimede, select, eş zamanlı olarak yürütülen rutinler üzerinde değerler almak veya göndermek için kullanılır. Örnekte

ana goroutine geçerli saati yürütme, bunun nedeni her zaman yürütüldüğünde. Ancak diğer goroutinler select deyiminde yürütüldüğünden, bu her zaman için yürütme şansı elde edemez, çünkü bir kez case kanal blokları yürütülür. seçmek ne

yapar: tüm engellenmesi halinde

  • , çoklu devam eğer biri
  • devam edebilirsiniz kadar bekler, bu rastgele birini seçer.
  • Kanal işlemlerinden hiçbiri devam edemez ve varsayılan deyim mevcutsa, bu yürütülür: varsayılan olarak her zaman çalıştırılabilir (diğer bir deyişle: çalıştırılmaya hazırdır).

Gönderme işleminde bir varsayılan deyimle seçili bir ifadede gönderme, gönderimin engellenmeyeceğini garanti eder!

sonsuza çalıştırmak döngü için kullanmak için:

package main 

import (
"fmt" 
"time" 
) 

func Remind(text string, delay time.Duration) <-chan string { //channel only for receiving strings 
    ch := make(chan string) // buffered/unbuffered? 
    go func() { 
     for { 
      msg := "The time is " + time.Now().Format("2006-01-02 15:04:05 ") + text 
      ch <- msg 
      time.Sleep(delay) // waits according to specification 
     } 
    }() 
    return ch 
} 

func main() { 
    ch1 := Remind("Eat", 1000*1000*1000*3) // every third second  
    ch2 := Remind("Work", 1000*1000*1000*8) // every eighth second 
    ch3 := Remind("Sleep", 1000*1000*1000*24) // every 24th second 
    for { 
     select { // chooses one channel that is not empty. Should run forever (?) 
     case rem1 := <-ch1: 
      fmt.Println(rem1) 
     case rem2 := <-ch2: 
      fmt.Println(rem2) 
     case rem3 := <-ch3: 
      fmt.Println(rem3) 
     } 
    } 
} 

http://play.golang.org/p/BuPqm3xsv6

+0

Cevabınız için teşekkürler. Kanal blokları ne anlama geliyor? Bunun bir tanımını bulmakta zorlanıyorum. – Sahand

+0

Düzenlenmiş cevabımı görün –