golang中的byte []通道用法

时间:2016-12-20 19:46:05

标签: go slice race-condition channel

我是golang频道的新手,并且有一种我无法解释的奇怪行为。 我正在获取REST命令,并希望计算它的主体上的哈希函数。 为此,我使用io.TeeReader(request.Body, &writerToHash)读取了正文,在那里我传递了我自己的实现io.Writer的类:

func (self *WriterToHash) Write(p []byte) (n int, err error) {
    n=len(p)
    fmt.println("WriterToHash  len=%v, buff=%v", n, p)  //PRINT 1
    self.BodyChannel <- p
    return n, nil
}

BodyChannel已定义:BodyChannel chan []byte

我使用这个类如下:

    writerToHash := sisutils.WriterToHash{
        BodyChannel:make(chan []byte, 1024)
    }
    writerToHash.StartListen()
    reqnew, _ := http.NewRequest("PUT", url, io.TeeReader(request.Body, &writerToHash))

听力部分:

func (wth *WriterToHash) StartListen() {
    wth.OutChannel = make(chan []byte, 1000)
    go func (self *WriterToHash) {
        done := int64(0)
        h := sha1.New()
        for done < MessageSize{
            buff := <- self.BodyChannel

            done += int64(len(buff))
            DPrint(5, "AccamulateSha1 Done=: %v, buff=%v", done, buff)  //PRINT 2

            actually_write, err := h.Write(buff)
            if err != nil ||  actually_write != len(buff) {
                log.Println("Error in sha write:" + err.Error())
                break
            }
        }
        bs := h.Sum(nil)
        self.OutChannel <- bs
    }(wth)
 }

我发送1000字节的消息。在调试模式下,消息总是以相同的方式拆分:1字节,999字节 - 我使用PRINT 1看到它。在这种情况下,everythong工作正常。 问题是当消息在Write函数中被拆分为更多部分时。在这种情况下,我在PRINT1中看到:

[第一个字节]:a

[next~450 bytes]:b,c,d,...

[last~550字节]:w,x,y,...

但是在PRINT 2中我看到了不同的图片:

[第一个字节]:a

[~450字节,但从最后一部分开始的地方开始]:w,x,y ......

[last~550字节]:w,x,y,...

我实际上是最后一次过去两次但是尺寸不一样。

我不知道为什么会这样,并会感激任何帮助。

1 个答案:

答案 0 :(得分:4)

来自io.Writer documentation

  

写入不得修改切片数据,即使是暂时的。实现不得保留p

您无法存储或重用传递给Write方法的切片。如果您想在其他地方使用该数据,您需要复制它

func (self *WriterToHash) Write(p []byte) (n int, err error) {
    b := make([]byte, len(p))
    copy(b, p)
    fmt.println("WriterToHash  len=%d, buff=%v", len(p), b)
    self.BodyChannel <- b
    return len(p), nil
}