2012-01-15 74 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 2012-01-15 21:59:02

+0

好的,完成了。显然,你可以把这个稍微提高一点。例如,您可能想要将通道存储在数组中。 – snim2 2012-01-15 22:55:42

+0

非常感谢= = – thwd 2012-01-15 23:15:44

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

哇哇!非常感谢你。我会更深入地分析一下。 – thwd 2012-01-15 23:41:33