2012-01-15 4 views
1

Пусть я разборе какой-то вход со следующими тремя способами:Синхронизированные каналы?

func parseHeader ([]byte) []byte 
func parseBody ([]byte) []byte 
func parseFooter ([]byte) []byte 

Они разбором некоторую часть того же входа и вернуть его как []byte, так что они могут быть использованы как это:

i := []byte(/* the input */) 
b := new(bytes.Buffer) 

b.Write(parseHeader(i)) 
b.Write(parseBody(i)) 
b.Write(parseFooter(i)) 

Теперь я хотел бы сделать эти 3 процесса параллельными, используя каналы. Моя идея заключалась в передаче канала этим функциям для записи, но как я могу убедиться, что они будут писать в правильном порядке на канал? (т.е., что тело записывается в канал после заголовка и колонтитула после тела)

ответ

5

По существу вы не можете, по крайней мере, без добавления дополнительного слоя сообщений, чтобы сделать дополнительные рамами встряхивая. Что лучше делать, так это использовать три отдельных канала и читать их в том порядке, в котором вы хотите их получить, поэтому вам не нужно беспокоиться о порядке отправки процессов отправки.

Вот минимальный пример:

package main 

import "fmt" 

func sendme(num int, ch chan int) { 
     ch <- num // send integer 'num' down chan ch 
} 

func main() { 
     // Create three new channels 
     one := make(chan int) 
     two := make(chan int) 
     three := make(chan int) 

     // Start each parallel invocation of "sendme" as a go routine, in any order 
     go sendme(3, three) 
     go sendme(1, one) 
     go sendme(2, two) 

     // Read from each channel in the order we wish to process the 
     // data 
     fmt.Println(<- one, <- two, <- three) 
} 
+0

Вы могли бы привести пример того, как я мог бы это сделать, используя 3 канала, пожалуйста? =), что было бы потрясающе. – thwd

+0

OK, сделано. Очевидно, вы можете немного подправить это. Например, вы можете захотеть сохранить каналы в массиве. – snim2

+0

Спасибо большое =] – thwd

1

Вот довольно полезный пример для вас, чтобы играть. У меня есть лишний материал, чтобы регистрировать последовательности, чтобы вы могли видеть, что все может закончиться не по порядку, но все равно отображаться в порядке, как можно скорее, но не раньше, чем когда закончится предыдущее.

package main 

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

func deferredString(lbl string, f func() string) (rv chan string) { 
    rv = make(chan string) 
    go func() { 
     s := f() 
     fmt.Printf("Finished %s\n", lbl) 
     rv <- s 
    }() 
    return rv 
} 

func do(rv string) string { 
    t := rand.Intn(5) 
    fmt.Printf("Sleeping for %d seconds for %s\n", t, rv) 
    time.Sleep(time.Duration(t) * time.Second) 
    return rv 
} 

func main() { 
    rand.Seed(int64(time.Now().Nanosecond())) 

    cha := deferredString("a", func() string { return do("a") }) 
    chb := deferredString("b", func() string { return do("b") }) 
    chc := deferredString("c", func() string { return do("c") }) 

    fmt.Printf("a: %s\n", <-cha) 
    fmt.Printf("b: %s\n", <-chb) 
    fmt.Printf("c: %s\n", <-chc) 
} 
+0

wow awesome! Большое спасибо. Я проанализирую это более подробно. – thwd

Смежные вопросы