1

次の 3 つのメソッドを使用して、ある種の入力を解析しているとします。

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 つのプロセスをチャネルを使用して並列化したいと考えています。私のアイデアは、これらの関数にチャネルを渡して書き込みを行うことでしたが、チャネルに正しい順序で書き込むことを確認するにはどうすればよいですか? (つまり、本文はヘッダーの後にチャネルに書き込まれ、本文のにフッターが書き込まれます)

4

2 に答える 2

5

基本的に、少なくとも、余分なハンドシェイクを行うためにメッセージのレイヤーを追加しない限り、それはできません。3つの別々のチャネルを使用し、それらを受信したい順序で読み取ることをお勧めします。これにより、送信プロセスの書き込み順序を気にする必要がなくなります。

最小限の例を次に示します。

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)
}
于 2012-01-15T21:01:09.233 に答える
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)
}
于 2012-01-15T23:28:54.893 に答える